let 特性

2017-11-07  本文已影响0人  LingJJ1100的笔记

说明:除了提供var的变量声明方法,
还提供了将变量绑定到所有的任意作用域中(通常是{..}内部)
换句话说:let,为其声明的变量隐式劫持了所有的块作用域

块作用域

ES5中:只有全局作用域和函数作用域
说明:花括号{..}包括的代码
但是:for while if中并没有块级作用域
解决:使用let 声明 或 使用闭包包裹

for(var i = 0; i < 5; i++){
    var a = 10;
    let b = 2333; 
}
// 貌似i和a 都定义在for的作用域内
// 实质是绑定到全局变量中
console.log(i, a) // 6 10
console.log(b) // ReferenceError: err not found

提升 编辑器的预编译

var 变量:声明会被提升,赋值则不会
let 变量:不会被提升
函数:会被提升
函数优先:函数相对于变量优先提升

console.log(a) // undefined
var a = 2; //a以被声明并赋值undefined 但未赋值2

b() // 2 
function b(){ console.log(1) }; // 被提升
function b(){ console.log(2) }; // 被提升并覆盖上个
var b  = function(){console.log(3)}; // 有函数被忽略

c() // TypeError
// c变量声明被提升,但未赋值。 undefined不能运算操作
var c = function(){console.log(1)}

let 和 for

for 和 var:for本省没有块作用域 需要使用闭包来来保存每一次的循环变量。
(循环变量)和{循环体}是父子作用域关系,在循环体内重复声明i不会影循环变量
for 每一次迭代:获取上一次循环变量,并从新声明新
当for使用let:由于每一次都是新的let声明,所以都是新的块作用域

// 用let 声明 i 让 i 成为块级作用域形成变量,
// 每一次的 i 只对当时的块作用域内有效。
for(let i = 0; i < 3; i++){
    setTimeout(()=>{ 
        console.log(i) // 0 1 2
    },1000)
}

for(let i = 0; i < 3; i++){
    let i = 'abc'; //声明 i 但不会覆盖 循环变量里面的i
    setTimeout(()=>{ 
        console.log(i) // 'abc' 'abc' 'abc'
    },1000)
}

暂时性死区 不能重复声明

说明:只要块级作用域内存在let变量,该声明的变量名不受外部的同名变量影响
使用:在变量正式被声明前,不能使用

let a = 10;
function foo(){
    //  a 被绑定,且let不会被提升
    console.log(a);// ReferenceError
    let a = 20; //let声明 的a变量,以上区域为死区
    let a = 30; // SyntaxError 重复声明报错
};
foo();
上一篇下一篇

猜你喜欢

热点阅读