挖掘javascript高级属性——作用域链(scope)
虽然js的的语法和c很相像,但是js变量的作用域是通过函数来划分的。
var name = "global";
function fun(){
var name = "local";
alert(name);
}
fun();
上面的这段代码非常简单吧,全局作用域window's[scope].name=global;fun's[scope].name=local;接着看如下代码:
var name="global";
function echo(){
alert(name);
}
echo();
function fun(){
var name="local";
echo();
}
fun();
运行结果是global,global。可能有些人会认为是global,local。其实这个example是要说明,scope在预解析的时候已经确定了。
关于作用域路径查找:
var name="global";
function fun1(){
function fun2(){
function fun3(){
alert(name);
}
fun3();
}
fun2();
}
fun1();
运行结果肯定是global,运行机制是由fun3 -> fun2 -> fun1 的作用域查找,直到找到name才停止。
不过这会存在性能的隐患,建议:访问局部变量的效率要比访问全局变量的效率要高,故减少作用域链的查找路径是可以提高性能的。
关于Function构造器:
var name = "global";
function fun(){
var name = "local";
var fun2 = function(){
alert(name);
}
var fun3 = Function('alert(name)');
fun2();
fun3();
}
fun();
通过Function构造器来创建的时候,其scope包含的是全局window对象
with改变了原有的作用域
var a = 10, b = 10;
with({a:20}){
var a = 30, b = 30;
console.log(a);
console.log(b);
}
console.log(a);
console.log(b);
结果是30,30,10,30
在with的内部,var a = 30,b = 30其实等价于a=30,b=30。因为前面讲到,js的在预解析时,a,b已经在前面定义了,wiht里面的只是起到赋值的作用。但是a在with的内部是存在的,a=30只是改变了{a:20}里面a的值,并没有改变全局变量a的值。

浙公网安备 33010602011771号