声明提升
变量声明提升:
a = 2;
var a;
console.log(a);
console.log(b);
var b = 3;
直觉上会认为第一次输出a的值为undefined,第二次输出b的值为3,但是真正的答案是2和undefined,是因为代码发生了如下变化
var a ;
a= 2;
console.log(a);
var b;
console.log(b);
b = 3;
定义变量会把变量提升到最前面,但是赋值过程会被留在原地等待引擎在执行阶段执行
知道了变量提升,现在来看看下面一段代码
console.log(a);
var a = 0;
function fn(){
console.log(b);
var b = 1;
function test(){
console.log(c);
var c = 2;
}
test();
}
fn();
//变量提升后,代码如下
var a;
console.log(a); //undefined
a = 0;
function fn(){
var b;
console.log(b); //undefined
b = 1;
function test(){
var c;
console.log(c); //undefined
c = 2;
}
test();
}
fn();
函数提升:
有函数声明和函数表达式两个概念,要对这两个进行区分
首先是函数声明
foo();
function f00(){
console.log(1);
}
上面的代码能输出1,就是因为foo()函数声明进行了提升,如下:
function foo(){
console.log(1);
}
f00();
然后是函数表达式,先看看函数表达式长什么样子
var demo = function fn1(){
//代码块
}
demo(); //正确的调用
fn1(); //错误的调用
//前后两个函数的名字可以相同,也可以不相同
//function后面的这个名字可以省略,并且只能在函数内部使用
函数声明会提升,但是函数表达式却不会
foo();
var foo = function(){
console.log(1); //报错 foo is not a function
}
变量标识符foo被提升分配给全局作用域,但是foo没有赋值,foo()对undefined值进行函数调用而导致非法操作,所以会抛出异常
可以看出,函数声明由于有函数提升,所以可以在任意位置调用,但是函数表达式没有函数提升,所以只能在函数表达式之后调用
test1(); //100
demo1(); //demo1 is not a function
function test1(){
console.log(100);
}
var demo1 = function test2(){
console.log(50);
}
变量声明和函数声明都会被提升,但是函数声明会覆盖变量声明
var a ;
function a(){}
console.log(a); //function a(){}
但是如果变量存在赋值操作,最终的值为变量的值
var a = 1;
function a(){}
console.log(a); //1