块级绑定

2019-10-08  本文已影响0人  皮皮灬
  1. 使用 var 声明的变量,会提升到当前作用域的最顶部或者是全局作用域,叫做变量提升 Hoisting 。
  2. 变量没声明 和 变量声明没赋值 是不一样的概念,使用 var 声明的变量的如果值是 undefined ,其实是声明了但没赋值,如果使用没有声明的变量会报错。
  3. let 声明
    const 声明,const 声明的变量不能被重新赋值,但是如果 const 声明的值是对象,那么这个对象是可以修改了。
var 的问题

1.即时调用函数表达式(immediately-invoked function expressions, IIFEs)
2.全局绑定 var 的问题

循环中的函数(Functions in Loops)

长久以来 var 声明的特性使得在循环中创建函数问题多,因为循环中声明的变量在块外也可以被访问,考虑如下的代码:

var funcs = [];

for (var i = 0; i < 10; i++) {
   funcs.push(function() { console.log(i); });
}

funcs.forEach(function(func) {
   func();     // 输出 "10" 共10次
});

你可能认为这段代码只是普通的输出 0 - 9 这十个数字,但事实上它会连续十次输出 “10”。这是因为每次迭代的过程中 i 是被共享的,意味着循环中创建的函数都保持着对相同变量的引用。当循环结束后 i 的值为 10,于是当 console.log(i)被调用后,该值会被输出。

为了修正这个问题,开发者们在循环内部使用即时调用函数表达式(immediately-invoked function expressions, IIFEs)来迫使每次迭代时创建一份当前索引值的拷贝,示例如下:

var funcs = [];

for (var i = 0; i < 10; i++) {
    funcs.push((function(value) {
        return function() {
            console.log(value);
        }
    }(i)));
}

funcs.forEach(function(func) {
    func();     // 输出 0,1,2 ... 9
});

这种写法在循环内部使用了 IIFE,并将变量 i 的值传入 IIFE 以便拷贝索引值并存储起来,这里传入的索引值为同样被当前的迭代所使用,所以循环完毕后每次调用的输出值正如所期待的那样是 0 - 9 。幸运的是,ECMAScript 6 中 let 和 const 的块级绑定对循环代码进行简化。

当 ECMAScript 6 还在酝酿中的时候,一个普遍的共识是使用 let 而不是 var 来作为默认的变量声明方式。对大多数 JavaScript 开发者来讲,let 才是 var 该有的表现形式,自然而然这种取代十分合理。在这个理念下,你应该使用 const 声明来保护一些变量不被修改。

然而,当越来越多的开发者迁移到 ECMAScript 6 之后,一个新的实践逐渐流行了起来:const 是声明变量的默认方式,仅当你明确哪些变量之后需要修改的情况下再用 let 声明那些变量。这个实践的缘由是大部分变量在初始化之后不应该被修改,因为这样做是造成 bug 的根源之一。这个理念有大批的受众而且在你接纳 ECMAScript 6 之后值得考虑。

上一篇 下一篇

猜你喜欢

热点阅读