本文总结一些关于JS解析机制的问题。
首先说明JS解析机制中变量提升的概念:变量提升即将变量声明提升到它所在作用域的最开始的部分,但只是将变量声明为undefined,之后在正式执行程序时才会执行后面的赋值表达式。
下面看一个程序:
(function(){
a = 5;
alert(window.a);
var a = 10;
alert(a);
})();
运行结果是 undefined 10
这里还要说明一点:js中没有带var关键字的变量都是隐式全局变量,即未用var声明的变量,js会自动将其作为全局变量并在全局作用域内进行隐式的声明。
于是程序可理解为按照下面顺序执行:
var a = undefined;
//因为函数体内的a=5前未加var,JS自动在全局作用域内进行的隐式声明 于是window.a = undefined(全局的变量是挂在在window上的)
(function(){
var a = undefined; //函数体内的var a=10 在预解析时变量声明被提升到作用域(此函数体内部)的顶部,此时a变成了这个函数体内的局部变量
a = 5; // 此时a已经变为局部变量,这里改变的只是函数体内a的值为5 于是window.a还是等于undefined
alert(window.a); //undefined
a = 10; //将局部变量a赋值为10
alert(a); //10
})();
下面看另一程序:
alert(a)
var a = 1;
alert(a)
function a(){alert(1)};
alert(a)
var a = 2;
alert(a)
function a(){alert(2)};
alert(a)
a()
上面的程序运行结果是什么?
先说函数提升的概念:函数的声明也会被提升到作用域的最上面,但是它会直接被声明为完整的函数,之后逐行执行程序时不会再进行声明。
一个需要注意的情况是:如果有var 和 function声明同一个变量(比如上面同名的a),那么var不会覆盖function的声明,function可覆盖var的声明。
程序可理解为如下形式:
var a = undefined; // a=undefined
function a(){alert(1)}; // a=function(){alert(1)}
var a = undefined; // 不可覆盖函数的声明 a=function(){alert(1)}
function a(){alert(2)}; // a=function(){alert(2)}
alert(a) // function(){alert(2)}
a = 1; // 执行a=1表达式 a=1
alert(a) // 1
function a(){alert(1)}; // 函数声明不会再执行 a还是=1
alert(a) // 1
a = 2; // 执行表达式 a=2
alert(a) // 2
function a(){alert(2)}; // 函数声明不会再执行 a还是=2
alert(a) // 2
a() // 此时a=2 于是这句实际是 3() 程序报错 a is not a function