博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[面试专题]从for循环看let和var的区别
阅读量:6847 次
发布时间:2019-06-26

本文共 1897 字,大约阅读时间需要 6 分钟。

从for循环看let和var的区别


MDN的let:

let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。与var关键字不同的是,var声明的变量只能是全局或者整个函数块的。在 ECMAScript 2015 中,let 绑定不受变量提升的约束,这意味着 let 声明不会被提升到当前执行上下文的顶部。在块中的变量初始化之前,引用它将会导致 ReferenceError(而使用 var 声明变量则恰恰相反,该变量的值是 undefined )。这个变量处于从块开始到 let 初始化处理的”暂存死区“之中。

循环定义中的let作用域:循环体中是可以引用在for声明时用let定义的变量,尽管let不是出现在大括号之间.

var list = document.getElementById("list");for (let i = 1; i <= 5; i++) {  var item = document.createElement("LI");  item.appendChild(document.createTextNode("Item " + i));  let j = i;  item.onclick = function (ev) {    console.log("Item " + j + " is clicked.");  };  list.appendChild(item);}

在每次循环的时候用 let j 保留的 i 的值,所以在 i 变化的时候,j 并不会变化。而console.log 的是 j,即使此处i声明换成var,结果依然一样.

MDN此处的写法是多余的,去掉let j = i依然可以实现上述效果,只是方便理解let.事实上去掉let j = i,等效于:

for (let i = 1; i <= 5; i++) {  //let i = i;即将i的作用域放在了改块级作用域中  var item = document.createElement("LI");  item.appendChild(document.createTextNode("Item " + i));  item.onclick = function (ev) {    console.log("Item " + i + " is clicked.");  };  list.appendChild(item);}console.log(i)// Uncaught ReferenceError: i is not defined

上边代码中最后的ReferenceError表明,i虽然在for循环{}的外层,但是实际上是被绑定在该块级作用域内的.这里和var是不一样的,var声明的i在外层,因此成为全局变量.

变量提升(hoist)

let x = "global";(function() {    console.log(x); // Uncaught ReferenceError: x is not defined    let x = 'part';    console.log(x)}());

众所周知,let变量没有hoist,按这个理解,函数内第一行log(x)应当是global才对,但是却报错了.去掉let x = 'part'就没有问题,这说明后边的声明影响到了第一行的log(x).

fn();function fn(){  var x = 1;  console.log(x,y)  var y = 2}

执行过程:

  1. 找到所有用 function 声明的变量,在环境中「创建」这些变量。

  2. 将这些变量「初始化」并「赋值」为 function(){//具体内容}

  3. 执行代码,即fn()

  4. 函数体内找到所有用var声明的变量,在环境中「创建」这些变量

  5. 将这些变量「初始化」为 undefined。

  6. 开始执行代码,x = 1 将 x 变量「赋值」为 1

  7. 打印x = 1 ,而y还未赋值,因此为undefined

    如果var改为let:

  8. 找到所有用 function 声明的变量,在环境中「创建」这些变量。

  9. 将这些变量「初始化」并「赋值」为 function(){//具体内容}

  10. 执行代码,即fn()

  11. 函数体内找到所有用let声明的变量,在环境中「创建」这些变量

  12. 开始执行代码,x = 1 将 x 变量「赋值」为 1

  13. 打印 x = 1 ,而y还未「初始化」,因此Uncaught ReferenceError.这就是所谓暂时性死区.

转载地址:http://eblul.baihongyu.com/

你可能感兴趣的文章