ES6之let和const

let

let的用法类似于var,但是let所声明的变量只在它所在的代码块有效。

与var进行比较:

{
    var a=100
    let b=200
}
console.log(a)    //100
console.log(b)    //ReferenceError: b is not defined

我们可以看到,在块内声明的b在块作用域外不能被访问。

这一特性经常被用在for循环中:

//用var声明i的for循环
var a=[];
for(var i=0;i<3;i++){
    a[i]=function(){
        console.log(i)
    }
}
a[2]();    //3

在上面的例子中,i的值是用var声明的,在全局范围内都有效,所以经过了所有的循环,i的值会变成最后一次循环的值,所以数组a中的每一个值都为3

而用let声明i,每次循环,i的值只在其块级作用域内有效,所以a数组的值分别为1,2,3:

//用let声明i的for循环
var a=[];
for(let i=0;i<3;i++){
    a[i]=function(){
        console.log(i)
    }
}
a[2]();     //2

对for循环的补充

for循环中的声明循环变量和循环体是父级作用域和子代作用域的关系:

for(let i=0;i<3;i++){
    let i='hello'
    console.log(i)
}

//hello 
//hello 
//hello

 

let声明方式的特点

1.不存在变量提升

var声明的变量可以在变量被声明之前被使用,而let限制了这一点,如果在let声明之前被使用,会抛出错误。

console.log(a)
var a;//undefined

 

console.log(b)
let b;//ReferenceError: a is not defined

2.暂时性死区

只要块级作用域内存在let生命的变量,那么这个变量就会绑定这个区域,不会受外部同名变量的影响。

var a=100;
{

    a=200           //ReferenceError: a is not defined
    console.log(a)  //ReferenceError: a is not defined
    let a
    a=300
    console.log(a)  //300
}

a在全局中声明,但是当块级作用域中用了他、声明了一个同名变量,这个变量就不能在声明前改变,相当于“划分了自己的领土范围”

一种更常见的死区:

function bar(x=y,y=2){
    return[x,y]
}

bar()//ReferenceError: y is not defined

暂时性死区也意味着typeof不再是一个百分百安全的操作

console.log(typeof c)
let c=1;   //ReferenceError: c is not defined

在这种情况下,type会抛出一个错误,而不是和var一样,返回undefined,所以这要求我们在使用let的时候,养成良好的编码习惯

3.不允许重复声明

let不允许在相同作用域内重复声明一个变量

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

在函数内重复声明参数也会报错

function func(arg){
    let arg
}

const

const声明的是一个常量,一旦声明,常量的值就不能改变:

const a=1;
a=2    //TypeError: Assignment to constant variable.

只声明不赋值也会报错

const a//SyntaxError: Missing initializer in const declaration

const声明的特点

const的本质保证的并不是变量的值不能改变,而是变量指向的那个内存地址不能改变。

对于简单数据类型:就相当于值不能改变

对于复杂数据类型:相当于指针指向的内存地址不能改变

const foo={}
foo.prop=100
console.log(foo.prop) //100 可以添加属性,指针指向的内存地址不变
foo={}//TypeError: Assignment to constant variable. //当改变指针的指向时,会报错

如果想要冻结复杂数据类型的属性,可以用Object.freeze

完全冻结的方法:

var constantize=(obj)=>{
    Object.freeze(obj)
    Object.freeze(obj).forEach((key,i)=>{
        if(typeof obj[key]==='object'){
            constantize(obj[key])
        }
    })
}

 

参考书籍:《ES6标准入门(第3版)》 阮一峰  

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值