ES6基础学习(一) - let 和 const

ES6基础学习(一) - 使用let 和 const声明变量

ES6为我们提供2个新的声明变量的方式:let,const。之所以会ES6会增加它们,这是因为在此之前声明变量是通过var 声明,但是这种声明方式偶尔出现我们预料之外的结果。举个栗子

var a = 2;

function test(){
    console.log(a);// 报错!!
    if(false){
        var a = 1;
    }
}

这是一个很常见的由’变量提升’导致报错的现象,具体原因这里就不做详细解释,我本来重点不讲这个问题。当然由var声明变量时引发的问题不仅仅是这些。接下来分别说说let和const。

let

用法跟var是类似的,但是实际上会有比较明显的区别:

let声明的变量仅作用于包含它的作用域中

在ES6之前不存在块级作用域,只有全局作用域和函数作用域。而ES6新增了块级作用域,所以这里所说的作用域是这三者。因此我们可以看到下面的一些栗子:

{
    let a = 2;
    console.log(a);
}

console.log(a);// 报错
if(true){
    let b = 2;
    console.log(b);
}
console.log(b);// 报错

正因为let拥有这种特性,我们可以处理一些之前比较麻烦的一些问题:

经典的循环体问题
var test = [];
for( var i = 0; i < 5 ; i++){
    test[i] = function(){
        console.log(i);
    }
}

a[3]();// 5

在ES6之前我们通常是利用闭包来解决


var test = [];
for( var i = 0; i < 5 ; i++){
    (function(i){
        test[i] = function(){
            console.log(i);
        }
    })(i);
}

a[3]();// 3

有let声明变量的方式,我们只需要将var替换为let就可以解决了

var test = [];
for( let i = 0; i < 5 ; i++){
    test[i] = function(){
        console.log(i);
    }
}

a[3]();// 3

这是因为每次循环都会生产一个块级作用域,而且它们是同级的,所以它们彼此之间互相独立,互不影响,而let声明的变量只在含有它的块级作用域内有效,所以每次循环i都是一个新的变量。

let声明不存在变量提升

let由于不存在变量提升的现象,所以变量一定要在其声明后再使用否则就会报错。

console.log(a);
let a  = 2;

这里再补充一个相关概念:

暂时性的死区(TDZ):在作用域内,在let声明该某变量之前,如果使用它,那么这之前的区域称为暂时性死区。JS引擎在扫描代码发现变量时,如果是var声明则直接提升至作用域顶部,如果是let和const声明则放入到TDZ中,只有执行声明变量后,才从TDZ中移除。

let不允许重复声明变量

不像var可以随意地重复声明变量,let不是不允许重复声明变量的。
’;

function(){
    let  a = 10;
    var a = 1;// 报错
}


function(a){
    {
        let a;//不报错
    }
    let a;//报错,这是因为函数的参数声明导致


}

const

const声明的变量是常亮,这也意味着其值不能改变的。

const a = 1;
a = 2;// 报错

然而是真的不能改变它的值,看看下面的栗子

const a = {};
a.test = 1;
console.log(a);//

从上面的栗子看出 const声明的对象a被新增了一个test属性,确实这个对象a被改变了,但是a的值并没有改变,因为对象是一种引用类型,所以a的值其实是指针,而这个指针是没有被改变的。所以变量a仍然没有改变。类似的栗子还有很多例如:

 const a  = [];
 a.push(1);

const的其他特性均与let相同,所以它不存在变量提升,不能重复声明,也只能在包含它的作用域中起作用。

var、let、const在for,for…in,for…of中的区别

var

var func = [];
for(var i = 0 ; i < 5 ; i++){
    func.push(function(){
        console.log(i);
    })
}

func.forEach(function(func){
    func()
});// 4
var func = [];
var obj = {
    a:1,
    b:2,
    c:3
}
for(var key in obj){
    func.push(function(){
        console.log(i);
    })
}

func.forEach(function(func){
    func()
});// 3

从此可以看出无论是哪种循环,var声明的在循环中只创建一次,所以最后我们自然而然就会看到类似的结果;

let

var func = [];
for(let i = 0 ; i < 5 ; i++){
    func.push(function(){
        console.log(i);
    })
}

func.forEach(function(func){
    func()
});// 0,1,2,3,4
var func = [];
var obj = {
    a:1,
    b:2,
    c:3
}
for(let key in obj){
    func.push(function(){
        console.log(i);
    })
}

func.forEach(function(func){
    func()
});// 1,2,3

在循环中用let声明变量,每一次循环都会创建一个新的变量。在for循环中会同时将其初始化当前该变量的值。

const

var func = [];
for(const i = 0 ; i < 5 ; i++){
    func.push(function(){
        console.log(i);// 报错
    })
}

func.forEach(function(func){
    func()
});
var func = [];
var obj = {
    a:1,
    b:2,
    c:3
}
for(const key in obj){
    func.push(function(){
        console.log(i);
    })
}

func.forEach(function(func){
    func()
});// 1,2,3

在for循环中const声明的变量由于只创建了一次所以会发生报错,而for…of,for…in每次循环都会创建一个新的变量,并给它赋值,所以不会发生错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值