深入理解ES6(2)

2017-11-12  本文已影响0人  Ztry

第1章 块级作用域绑定


1. var声明及变量提升(Hoisting)机制

function getValue(condition){
    if(condition){
        var value = "blue";
        // ...
        return value;
    }else{
        // 可访问value,其值为undefined
        return null;
    }
    // 可访问value,其值为undefined
}
<!-- 以上函数等同于以下的 -->
function getValue(condition){
    var value;
    if(condition){
        value = "blue";
        return value;
    }else{
        return null;
    }
}
//变量提升机制不止在函数中的局部变量,全局变量也有提升

2. 块级声明

2.1 let声明

function getValue(condition){
    if(condition){
        let value = "blue";
        return value;
    }else{
        //此处value不存在
        return null;
    }
    //此处value不存在
}

2.2 禁止重声明

var count = 30;
let count = 40; //TypeError
if (condition){
    let count = 40; //内嵌不会,可以重声明,作用域不同

2.3 const声明

//const声明的是常量,使用const要初始化并且不可更改
const maxItems = 30;
const name; //SystaxError

2.3.1 const & let

var message = "Hello!";
let age = 25;
//以下报错 TypeError
const message = "Goodbye";
const age = 30;
const maxItems = 5;
maxItems = 6;//TypeError;
const person = {
    name: "Nicholas"
};
//可以修改对象属性值
person.name = "Greg";
//不可以修改对象本身
person = {
    name: "Greg"
};

2.4 临时死区(Temporal Dead Zone)

if(condition){
    console.log(typeof value); //ReferenceError
    let value = "blue";
}
//对比
if(condition){
    console.log(typeof value); //"undefined"
    var value = "blue";
}
//对比
console.log(typeof value); //"undefined"
if(condition){
    let value = "blue";
}

3. 循环中的块作用域绑定(笔试面试常考)

for(var i = 0;i < 10;i++){
    process(items[i]);
}
console.log(i); // 10
for(let i =0;i<10;i++){
    process(items[i]);
}
console.log(i); //RerefenceError

3.1 循环中的函数

var funcs = [];
for(var i = 0;i<10;i++){
    funcs.push(function(){
        console.log(i);
    });//这个只是把函数放进去数组,并没有调用
}
funcs.forEach(function(func){
    func(); //输出10个10
});
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,3,4,5,6,7,8,9
});

3.2 循环中的let声明

var funcs=[];
for(let i = 0;i<10;i++){
    funcs.push(function(){
        console.log(i);
    });
}
funcs.forEach(function(func){
    func();//输出0,1,2,3,4,5,6,7,8,9
})
var funcs=[];
obj = {
    a: true,
    b: true,
    c: true
};
for(let key in obj){
    funcs.push(function(){
        console.log(key);
    });
}
funcs.forEach(function(func){   //func是funcs中的每一项
    func(); //输出a,b,c
});

3.3 循环中的const声明

var funcs=[];
for(const i = 0;i<10;i++){
    console.log(i);//第二次就报错了: TypeError:Assignment to constant variable
}
var funcs=[];
obj = {
    a: true,
    b: true,
    c: true
};
for(const key in obj){
    funcs.push(function(){
        console.log(key);
    });
}
funcs.forEach(function(func){
    func();//输出a,b,c
});

4. 全局块作用域绑定

var RegExp = "hello!";
console.log(window.RegExp); //”hello!"
var ncz = "Hi";
console.log(window.ncz);    //"Hi"
let RegExp = "Hello!";
console.log(RegExp);    //"Hello!"
console.log(window.RegExp === RegExp); //false
const ncz = "Hi!";
console.log(ncz);   //"Hi!"
console.log("ncz" in window); //false

5. 块级绑定最佳实践的进化

小结

  1. 块级作用域绑定的let和const为js引入词法作用域,他们声明的变量不会提升,只能在声明的代码块中使用;
  2. 临时死区(TDZ):变量声明前访问块级绑定导致错误的位置
  3. let & const 与 var 在循环中的差异
  4. 块级绑定的最佳实践:默认使用const,需要变化的值用let
上一篇 下一篇

猜你喜欢

热点阅读