<html> <head> <script> function f(){ a = 1; //全局变量a赋值为1 var b = 2; 局部变量b赋值为2 } try{ alert(a); } catch(e){ alert(e.message); //变量a未定义 } f(); //调用函数 alert(a); //1 </script> </head> </html>
变量的赋值操作发生在javascript执行期,而不是预编译期,在函数未调用前,函数内部定义的全局变量是无效的。
<html> <head> <script> var a = 1; //声明并初始化全局变量 (function f(){ alert(a); //undefined var a = 2; //声明并初始化局部变量 alert(a); //2 })(); </script> </head> </html>
由于函数内部声明了一个同名局部变量a,所以在预编译期,javascript就是用该变量覆盖掉拳击变量对于函数内部的影响,而在执行初期,局部变量a未赋值,所以在第一行读取局部变量a的值也就是undefined了。
<html> <head> <script> var a = 1; var b = 2; function f(){ var a = 3; function f(){ alert(a); //读取变量a的值,返回3 var b; //声明局部变量b alert(b); //读取局部变量b的值,undefined } return f; } var c = f(); c(); </script> </head> </html>
在闭包函数中,变量的作用域并没有因为使用闭包而发生改变,同时函数与闭包之间的作用域链也没有因为闭包而破坏,
<html> <head> <script> var a = 1; (function(){ var b = 2; (function(){ var c = 3; (function (){ var d = 4; alert(a+b+c+d); //10 })() })() })() </script> </head> </html>
javascript 解释器首先在最内层调用对象中查询属性a,b,c,d,其中只发现了属性d,并获取它的值,然后沿着作用域链,在上一层调用对象中继续查询查找属性a,b,c,以此类推。