Appearance
let & const & var
变量提升
var 和 function 存在变量提升机制,而 let、const、class、import 都不存在。
存储位置
全局作用域下 var 和 function 声明的变量存储到 GO 中,相当于给 window 设置属性。 没有基于关键字修饰而声明的变量,其实是省略了 window,相当于给 window 设置属性。 全局作用域下 let 和 const 等声明的变量存储到 VO(G) 中,和 window 没有关系。
重复声明
var 和 function 语法上允许相同上下文中重复声明一个变量,只不过浏览器解析时,会忽略 掉重复的声明。 let 和 const 等在语法上不允许相同上下文中重复声明,直接报错 [SyntaxError](语法错误) 检测是否重复声明的事情,不是发生在代码执行阶段,而是在词法分析阶段,如果有重复声明的 语法错误,则 AST 都不会生成,所以词法解析不通过,JS 任何代码都不会执行。 const 声明的变量必须设置初始值且不能修改它的关联指向。
块级作用域
除函数和对象的花括号外,如:判断体/循环体/代码块等花括号中出现了 let、const、function、class 关键字声明的变量,则当前花括号会产生一个块级私有上下文, 它的上级上下文是所处的环境,var 不产生块级上下。
暂时性死区
javascript// typeof 检测一个未被声明的变量,不会报错,结果是 'undefined'区。 console.log(typeof a)javascript// 如果这个变量使用了 let 声明,在声明之前使用 typeof 检测,会报错。 // 因此 let 或 const 声明的变量在代码执行到声明变量之前,声明的变量都处于 // “暂时性死区”之中,尚未初始化,访问将报错。 console.log(typeof a) // ReferenceError: Cannot access 'a' before initialization let a = null
js
// 输出几次,结果是多少?
// 词法检测检测当前即将执行代码是否会出现语法错误(SyntaxError),
// 如果出现错误,代码将不会再执行(第一行都不执行)
// example1
console.log(1)
let a = 12
console.log(a)
let a = 13 // SyntaxError(语法错误): Identifier 'a' has already been declared
console.log(a)
// example2
console.log(1)
console.log(a) // ReferenceError(引用错误): Cannot access 'a' before initialization
let a = 12
// example3
console.log(a)
var a = 12
let a = 13 // SyntaxError: Identifier 'a' has already been declared
console.log(a)
// example4
console.log(a)
let a = 13 // SyntaxError: Identifier 'a' has already been declared
var a = 12
console.log(a)
// example5
function sum (a) {
console.log(a)
let a = 100
console.log(a)
}
// example6
function foo () {
function sum (a) {
console.log(a)
let a = 100
console.log(a)
}
}
// example
// 匿名函数具名化比较特殊,能通过词法解析,function fn中的fn保存在函数的AO(FN)中,但仍可以使用let重复声明,fn权重太低?
let fn = fubction fn () {
let fn = 10
console.log(fn)
}