1,eval()
eval(…) 函数可以接受一个字符串为参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。
看一个例子:
function foo(str, a) {
eval( str ); // 欺骗!
console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1, 3
eval(…) 调用中的 “var b = 3;” 这段代码会被当作本来就在那里一样来处理。由于那段代
码声明了一个新的变量 b ,因此它对已经存在的 foo(…) 的作用域进行了修改。因此会输出1, 3
2,with
with 通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象
本身。
比如:
var obj = {
a: 1,
b: 2,
c: 3
};
// 单调乏味的重复 "obj"
obj.a = 2;
obj.b = 3;
obj.c = 4;
// 简单的快捷方式
with (obj) {
a = 3;
b = 4;
c = 5;
}
再看一个例子:
function foo(obj) {
with (obj) {
a = 2;
}
}
var o1 = {
a: 3
};
var o2 = {
b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 ,a 被泄漏到全局作用域上了
为什么执行foo( o2 ); 之后o2.a时undefined呢?
当 o2 传递进去, o2 并没有 a 属性,因此不会创建这个属性,o2.a 保持 undefined 。
可为什么a会在全局作用域中呢?
在执行with(o2)时,o2中并没有 a 标识符,然后会继续在foo()的作用域中寻找a,没找到的话就接着往下找,最后在全局作用域中都没有找到标识符 a,因此当 a=2 执行时,自动创建了一个全局变量