咏竹莉
where there is a will,there is a way

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

 

posted on 2021-03-04 10:44  咏竹莉  阅读(138)  评论(0)    收藏  举报