let关键字的理解

600 阅读3分钟

在es6出来之后,很多人开始使用其中的语法,今天我想记录一下自己对let的一些理解。

不许重复声明

let与var不同,let不允许一个变量进行重复声明。

    let i = 4
    let i = 3
    console.log(i)

这个时候会报错

同样的代码,将let改为var关键字声明就不会报错

    var i = 4
    var i = 3
    console.log(i)

那如果一个用var声明一个用let声明会不会报错呢,代码如下

    var i = 4
    let i = 3
    console.log(i)

一样会报错。

值得注意的是如果一个函数有参数,let也不能重复声明。举个例子

    function f1(i) {
    	let i = 3
    	console.log(i)
    }
    f1()

一样会报错

不能重复声明的限制条件

let是不允许在相同的作用域重复声明的,但是在不同的作用域中是可以重复声明的,一个简单的例子

    function f1() {
    	let i = 3
    	console.log(i)
    }
    function f2() {
    	let i = 4
    	console.log(4)
    }
    f1()
    f2()

运行结果如下:

因为这两个i在不同的两个函数体内,属于不同的作用域,所以不会报错

不存在变量提升

在以前使用var的时候会出现变量提升的情况

    console.log(i)
    var i = 0

运行结果如下

如果将代码改成下面这样呢?

    console.log(i)
    let i = 0

运行结果如下

是的,浏览器提醒我们初始化之前无法访问这个变量

块级作用域

看下一段代码

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

这个会不会报错呢?运行结果如下

按照我们之前说的let拥有不能重复声明的属性,应该报错才对。为什么没有报错呢,这就涉及到了let的另一个属性块级作用域。在有{}包裹的时候,let就会是一个块级作用域。我是这样理解的,相当于在for循环的外面套了一层function。

    var i = 3
    if (true) {
    	let i = 4
    	console.log(i)
    }

一样不会报错,运行结果如下

暂时性死区

如果一个作用域内有let声明的变量了,那就会影响这个作用域,不会被外部的变量影响,举个例子

    var i = 3
    if (true) {
    	console.log(i)
    	let i = 4
    }

运行结果如下

此时一样会报错。我们已经声明了全局变量i,但是我们在这个if内部使用let又进行了声明,所以let“绑定”(binding)在这个作用域里面,所以会报错。

总之在一个作用域里面,或者说是代码块里面,使用let命令声明的变量,在声明之前是不能使用的。这在语法上称为“暂时性死区”

“暂时性死区”也导致了typeof不是一个安全的操作,比如说

    typeof i
    let i = 3

运行结果如下

如果没有使用let进行声明,也就是将上述代码的let i = 3,这句话删除,只剩下typeof i则不会报错

头一回写技术文章,还请大佬们多多指出错误

参考阮大神的es6.ruanyifeng.com/#docs/let