JS基础 —— 变量提升
测试环境 chrome 79.0.3945.79 (正式版本) (64 位) (cohort: Stable)
“变量提升”并不是说变量和函数的声明会在物理层面移动到代码的最前面!实际上,变量和函数声明在代码里的位置是不会动的,而是在编译阶段被放入内存中!
变量提升 & 函数提升
先看下面两段代码
foo();
var foo = function(){
console.log('变量');
}
foo();
function foo(){
console.log('函数');
}
foo();
// 输出
函数
变量
变量
预编译后
// 函数声明提升优先级比变量声明高,也就是说,函数声明提升比较靠前
function foo(){
console.log('函数');
}
var foo; // 由于未初始化,所以不覆盖上面的
foo(); // 此时foo还是函数 --> 函数
foo = function(){
console.log('变量');
}
foo(); // foo被变量覆盖了 --> 变量
foo(); // 无变化 --> 变量
foo();
function foo(){
console.log('函数');
}
foo();
var foo = function(){
console.log('变量');
}
foo();
// 输出
函数
函数
变量
预编译后
function foo(){
console.log('函数');
}
var foo;
foo();
foo();
foo = function(){
console.log('变量');
}
foo();
参考MDN后
猜测:预编译的时候,函数声明和变量声明都会提升(提升后的相对位置,在下面大胆猜测一下),变量未初始化会被忽略,变量初始化后会覆盖同名变量和函数。
-
猜测1:变量声明和函数声明按照相对位置(script中定义的位置)提升,但是变量提升时总是未初始化的,所以遇到同名变量,直接忽略,知道运行到变量初始化的位置,前边同名的值会被覆盖
猜测2:变量声明总是在函数声明前,或总是在其后(可以分别保存在堆的两块空间里)
- 变量声明在函数声明前,则一致采用覆盖原则
变量声明在函数声明后,则遇到未初始化的时候采取忽略原则,否则覆盖
实践如下↓
var声明的变量和function声明的函数同名的情况
// 变量
var a; // 声明
var a = num; // 声明 + 初始化
// 函数
function fun(){}; // 声明
-
var声明的变量同名:取后声明的,如果后声明的已经初始化了(包括undefined值)。
-
function声明的函数同名:取后声明的。
-
var变量和function函数同名:取变量,如果变量已经初始化了(包括undefined值);否则取函数。
let和const不能重复声明变量
报错:Uncaught SyntaxError: Identifier 'num' has already been declared
浙公网安备 33010602011771号