第二章 词法作用域
欺骗词法,Javascript中有两种机制来实现这个目的, eval和with。
欺骗词法作用域会导致性能下降。
1.eval
function test(str, a){
eval(str); //欺骗
console.log(a, b);
}
var b = 2;
test("var b = 3;", 1); //1, 3
程序运行时,eval(str)会变换成var b=3; 此时test函数作用域中的b声明覆盖了全局作用域中b的声明。所以test中输出b是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 test(obj){
with(obj){
a = 2;
}
}
var o1 = {
a : 3
};
var o2 = {
b : 3
};
test(o1);
console.log(o1.a); // 2
test(o2);
console.log(o2.a); // undefined
console.log(a); // 2-----不好,a被泄露到全局作用域上了
由于o1中有a属性,所以test(o1)时,o1中的a被赋值为2;o2中没有a属性,test(o2)时,o2作用域中没有a的声明,再上一级test函数作用域中也没有a的声明,再上一级全局作用域中没有a的声明,由于a=2是LHS,所以在全局作用域中隐式创建了a的全局声明。于是在全局打印a的时候会输出2。
另外一个不推荐使用eval()和with()的原因是会被严格模式所限制。with被完全禁止,而在保留核心功能的前提下,间接或非安全地使用eval()也被禁止了。
posted on 2019-02-05 18:24 atomgame的记事本 阅读(57) 评论(0) 收藏 举报