JavaScript声明提升

 一般认为,javascript代码在执行时是由上到下一行一行执行的。但实际上这并不完全正确,主要是因为声明提升的存在。 

变量声明提升 

a = 2 ;
var a;
console.log( a ); //2

一般来说会认为结果是undefined,因为var a声明在a = 2;之后,变量应该被重新赋值了,被赋予默认值undefined。但是,真正的输出结果是2

console.log( a ) ; //undefined
var a  =  2 ;

简单调整一下,根据第一次的结果,可能会认为这个代码片段也会同样输出2。但真正的输出结果是undefined

这些和观感相背的原因在于编译器的编译过程

引擎会在解释javascript代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来

包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理

var a = 2 ;这个代码片段实际上包括两个操作:var a 和 a = 2 

第一个定义声明是在编译阶段由编译器进行的。第二个赋值操作会被留在原地等待引擎在执行阶段执行

var a;
console.log(a);
a = 2 ;

 所以第二段代码实际是这样,声明从它们在代码中出现的位置被“移动”到了最上面,这个过程就叫作提升。

函数声明提升

foo();   //1
function foo(){
    console.log(1);
}

这段代码之所以能够在控制台输出1,就是因为foo()函数声明进行了提升

function foo(){
    console.log(1);
}
foo();

函数声明会提升,但函数表达式却不会提升 

foo();  //TypeError: foo is not a function
var foo = function(){
    console.log(1);
}

这段代码中的变量标识符foo被提升并分配给全局作用域,因此foo()不会导致ReferenceError。但是foo此时并没有赋值,foo()由于对undefined值进行函数调用而导致非法操作,因此会抛出TypeError异常

//变量提升后,代码如下所示:
var foo;
foo();
foo = function(){
    console.log(1);
}

猜你喜欢

转载自blog.csdn.net/qq_42265289/article/details/81258470