1. let 命令
基本用法
ES6 新增了let命令,用来声明变量,它的用法类似var,但是所声明的变量,只在let命令所在的代码块内有效
不存在变量提升
var 命令会发生“变量提升”现象,即变量可以在声明之前使用,值为undefined。这种现象多少是有些奇怪的,按照一般的逻辑,变量应该在申明语句之后才可以使用。
为了纠正这种现象,let命令改变了语法行为,它所申明的变量一定要在申明后使用,否则报错。
// var 的情况 console.log(foo); // 输出undefined var foo = 2; // let的情况 console.log(bar); // 报错 let bar = 2;
上面代码中,变量foo用var声明,会变量提升,即脚本开始运行时,变量foo已经存在了。但是没值,所以会输出undefined。变量bar用let申明,不会发生变量提升,所以会报错
暂时性死区
只要块级作用域内存在let命令,它所声明的变量就绑定这个区域,不再受外部的影响。
var tmp = 123; if (true) { tmp = 'abc'; // 会报错 let tmp; }
上面代码中,存在全局变量tmp,但是块级作用域内let又声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明变量前,对tmp赋值会报错。
ES6明确规定,如果区域中存在let和const命令,这个区块对这个命令声明的变量,从一开始就行程了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区” (简称TDZ)
if(true) { tmp = 'abc'; // 报错 console.log(tmp); // 报错 let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
ES6 规定暂时性死区和let、const 语句不出现变量提升,主要为了减少运行时错误,防止在变量声明前就使用这个变量,从而导致意料之外的行为。
不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
// 报错 function func() { let a = 10; var a = 1; } // 报错 functiob func() { let a = 10; let a = 1; }
因此,不能在函数内部重复声明参数
function func(arg) { let arg; } func() // 报错 function func(arg) { { let arg; } } func() // 不报错
为什么需要块级作用域?
第一种场景,内层变量可能会覆盖外层变量
var tmp = new Date(); function f () { console.log(tmp); if (false) { var tmp = 'Hello world'; } } f(); // undefined
第二种场景,用来计数的循环变量泄露为全局变量
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); } console.log(i); // 5
上面代码中,变量i只用来控制循环,但是循环结束后,它并没有消失,泄露成了全局变量。
总结:
1. var 没有块级作用域,支持变量提升
2. let 有块级作用域,不支持变量提升,不允许重复声明,暂存性死区,不能通过window.变量名进行访问
3. const 有块级作用域,不支持变量提升,不允许重复声明,暂存性死区,变量一旦声明不能改变,改变报错。
在图片上传校验尺寸中用了promise对象,详见上篇随笔
详见: https://www.runoob.com/w3cnote/javascript-promise-object.html
浙公网安备 33010602011771号