记住:exclamation:当js执行的时候遇见var
和function函数
的时候,将会出现变量声明提前。这个过程也被叫做,“预解析”或者“预编译”。
两种方式不同处:
- 对var 声明只是将声明提前,
赋值
仍然保留在原位置
; - function 声明,会将函数名称和函数体
都提前
,而且先预声明变量
再预定义函数。
简单例子:
var声明代码段
console.log(a); //不会出错,会输出undefined
var a=100;
console.log(a); //100;
由于从上往下执行时遇见了var
,所以实际执行顺序:
var a; //声明提前
console.log(a);//undefined
a=100; //赋值任然留在原位置
console.log(a);//100
- 声明提前仅能将声明提前到
所在作用域
的顶部。如下所示:在函数中的var,则将声明提到函数内
的第一行。
function fn(){
console.log(a); //undefined
var a=100;
console.log(a); //100
};
fn();
console.log(a);// 报错未定义!
实际执行:
function fn(){
var a; //仅仅提前到函数顶部
console.log(a); //undefined
a=100;
console.log(a); //100
};
fn();
console.log(a); //报引用错误
function声明代码段
console.log(fn()); //2
function fn(){
return 2;
}
实际执行:
var fn;
fn = function{
return 2
}
console.log(fn());
:point_right:以下是两个声明综合的小例子:
var a=123;
function a(){ return 1 }
console.log(a);
实际执行:
var a;
function a(){ return 1 }
a=123;
console.log(a); //123
由此可见,函数声明的优先级比var声明更高,如果两者同时存在,则先执行函数提前声明。
es6 的 let 则无此问题,是es5的严格模式,所不存在变量提前,但会有暂时性死区。