ES6 中块级作用域及新变量声明新语法 let 详解

1,030 阅读1分钟
原文链接: www.36nu.com

ES6之前js没有块级作用域,它使用var声明变量,以function来划分作用域,大括号“{}” 却限定不了var的作用域,用var声明的变量具有变量提升(declaration hoisting)的效果。ES6新增加了一个let,可以在{}, if, for里声明。用法同var,但作用域限定在块级,let声明的变量不存在变量提升。

例1: 块级作用域 if

function test(flag) {
    if (flag) {
        var a = 'js'
    } 
    // 这里也可以访问 a
}

变量a在if块里声明的,但在else块和if外都可以访问到val,把var换成let后:

function test(flag) {
    if (flag) {
        let a = 'js'
    } 
    // 这里也访问不到 a
}

例2块级作用域 for

for(var i=0; i<2; i++){
    console.log('outer i: ' + i);
    for(var i=0; i<2; i++){
	console.log('inner i: '+i);
    }
}

执行结果如下:

outer i: 0
test.html:12 inner i: 0
test.html:12 inner i: 1

可以看到,外层循环被打断了,因为i为全局变量所以 i 的值被内层循环修改了,把内层循环的var换成let后:

for(var i=0; i<2; i++){
    console.log('outer i: ' + i);
    for(let i=0; i<2; i++){
	console.log('inner i: '+i);
    }
}

执行结果如下:

outer i: 0
test.html:12 inner i: 0
test.html:12 inner i: 1
test.html:10 outer i: 1
test.html:12 inner i: 0
test.html:12 inner i: 1

示例3: 变量提升

先使用后声明

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

变量val先使用后声明,输出undefined,也不报错。把var换成let,就报错了

console.log(a) // Uncaught ReferenceError: a is not defined
var a;

先判断后声明

if (typeof a == 'undefined') {
    // ...
}
var a = ''

把var换成let,if处报语法错 Uncaught ReferenceError: a is not defined

if (typeof a == 'undefined') {
    // ...
}
var a = ''

ES6规定,如果代码块中存在let,这个区块从一开始就形成了封闭作用域,凡是在声明之前就使用,就会报错。即在代码块内,在let声明之前使用变量都是不可用的。