要记住
- 声明是在编译阶段进行,而赋值是在执行阶段进行。
function fn() {}
是声明加强制赋值行为- 变量提升的两个解释,一个是函数声明首先被提升,然后才是变量,第二个是不管哪个声明优先,按顺序来就好,但是后面的重复声明是没有用的。
- 后面的赋值行为会覆盖前面的赋值行为
看第一段代码
console.log(fn) // [Function: fn]
var fn = 1
function fn() {}
console.log(fn) // 1
按照第一个解释,代码是下面这样:
var fn
function fn() {}
console.log(fn)
fn = 1
console.log(fn)
按理来说function fn() {}
是重复声明,但是它同时还是赋值行为...所以覆盖了前面的var fn
🐶🐶🐶
第二个解释的话代码等同于下面这个样子:
function fn() {}
var fn
console.log(fn)
fn = 1
console.log(fn)
后面的var fn
是对变量的重复声明,所以被忽略了🐶🐶🐶...
第二段
console.log(i) // undefined
for (var i = 0; i < 3; i++) {
console.log(i) // 1 \n 2 \n 3
}
等同于:
var i
console.log(i)
for(i=0; i< 3; i++){
console.log(i)
}
第三段
var a = 1
function fn() {
a = 2
console.log(a) // 2
var a = 3
console.log(a) // 3
}
fn()
console.log(a) // 1
等同于:
var a
function fn(){
var a
a = 2
console.log(a)
a = 3
console.log(a)
}
a = 1
fn()
console.log(a)
还有
尽管重复的var
声明会被忽略掉,但出现在后面的function
声明还是可以覆盖前面的,因为还具有强制赋值功能啊...
let
和const
这两个声明不存在变量提升,但存在暂存性死区,即变量在声明前使用是会报错的。
a = 1
let a
console.log(a) // Uncaught ReferenceError: a is not defined
b = 2
const b
console.log(b) // Uncaught SyntaxError: Missing initializer in const declaration