JavaScript引擎的工作方式是,先解析代码,获取所有被公告的变量,而后再一行一行地运行。这造成的结果,就是所有的变量的公告语句,都会被提升到代码的头部,这就叫做变量提升。
示例:
console.log(a) // undefinedvar a = 1function b() { console.log(a)}b() // 1
上面的代码实际执行顺序是这样的:
第一步 引擎将var a = 1拆解为var a = undefined和 a = 1,并将var a = undefined放到最顶端,a = 1还在原来的位置;
var a = undefinedconsole.log(a) // undefineda = 1function b() { console.log(a)}b() // 1
第二步 就是执行,因而js引擎一行一行从上往下执行就造成了当前的结果,这就叫变量提升。
当前作用域内的公告都会提升到作用域的最前面,包括变量和函数的公告
(function(){ var a = "1"; var f = function(){}; var b = "2"; var c = "3";})();
变量a,f,b,c的公告会被提升到函数作用域的最前面,相似如下:
(function(){ var a,f,b,c; a = "1"; f = function(){}; b = "2"; c = "3";})();
请注意函数表达式并没有被提升,这也是函数表达式与函数公告的区别。进一步看二者的区别:
(function(){ //var f1,function f2(){}; //hoisting,被隐式提升的公告 f1(); //ReferenceError: f1 is not defined f2(); var f1 = function(){}; function f2(){}})();
上面代码中函数公告f2被提升,所以在前面调用f2是没问题的。尽管变量f1也被提升,但f1提升后的值为undefined,其真正的初始值是在执行到函数表达式处被赋予的。所以只有公告是被提升的。