ES6新增了let关键字。今天来讨论一下,let关键字有哪些特性?
1、不存在变量提升
初学js的时候我们就知道,使用var关键字定义的变量会存在“变量提升”的情况,什么意思呢?就是变量在声明之前可以被访问,正是由于这个特性的存在,所以会出现各种奇怪的结果。
在ES6中,使用let定义的变量就不存在变量提升啦,如果你在变量声明之前去使用变量,就会“抛出异常”。
// var声明变量 console.log(a); // undefined var a = 'Andy'; // let声明变量 console.log(b); // ReferenceError: b is not defined let b = 'Daisy';
2、存在暂时性死区
暂时性死区,简单来讲就是,在使用let声明变量之前,该变量都是不可访问的。
if(true) { // 暂时性死区开始 c = 'Daniel'; console.log(c); // ReferenceError: c is not defined // ...... // 暂时性死区结束 let c; }
因为有typeof的存在,typeof运算符不再是绝对安全的了,在let定义的变量之前使用typeof运算符会抛出异常。
typeof d; // ReferenceError: d is not defined let d;
而ES6之前(非let或const声明的变量),使用typeof运算符是绝对安全的,处理一个未声明的变量时会返回”undefined”
3、不能重复声明
在同一个作用域内,不能使用let重复声明相同的变量。
function foo() { let arg1 = 'air'; if(true) { let arg1 = 'air'; } var arg1 = 'air'; // SyntaxError: Identifier 'arg1' has already been declared }
我们看下foo()这个函数内部,使用let和var同时声明了名为arg1的变量,因为是处于同一个作用域,所以抛出了异常。
而if(true){}那个代码块中使用let定义变量arg1不会抛异常,因为它只在代码块内有效,跟外面声明的变量arg1是相互独立的,所以可以正确定义。
我们可以由此得到一个启示,在函数内部,如果处于相同作用域,不可以重复声明和“形参”相同的变量名。
我们来看个例子:
function foo(arg1) { let arg1 = 'air'; // SyntaxError: Identifier 'arg1' has already been declared if(true) { let arg1 = 'air'; } }
第二行之所以抛出异常,是因为,使用let声明了一个与形参相同的变量arg1,这两个变量同处于函数级作用域中,所以会抛出异常。
在这里注意一下,是“处于相同作用域下”才会抛异常哦。
4、不再是全局对象的属性
在ES6之前,使用var声明的变量、函数表达式或函数声明都是window对象的属性。
有了ES6之后,如果我们使用let声明的变量或函数表达式,将不再是window对象的属性。
// var声明的变量和函数表达式 var a = 1; var fn = function() { console.log('global method'); }; console.log(window.a); // 1 window.fn(); // global method // let声明的变量和函数表达式 let b = 2; let foo = function() { console.log('global method'); }; console.log(window.b); // undefined window.foo(); // TypeError: window.foo is not a function