词法作用域意味着作用域是由书写代码时函数声明的位置来决定的。
作用域查找会找到第一个匹配的标识符时停止
欺骗词法作用域会导致性能的下降:
(1)eval()可以计算表达式,但不要把eval()函数传递的String对象来作为参数。如果试图覆盖eval属性或把eval()方法赋予另一个属性,并通过该属性调用它,则ECMAScript实现允许抛出一个EvalError异常,EvalError类表示:如果用户代码调用eval()函数或视图将new运算符用于Function对象,则会出现该错误。
function foo(str,a){
eval(str);//欺骗词法
console.log(a,b);
}
var b=2;
foo("var b=3;",1);//1,3动态插入声明了变量b,并且遮蔽了外部作用域中的同名变量,当然在严格模式下,无法动态修改所在作用域
( 2)with关键字:with通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复
引用对象本身。with声明实际上是根据你传递给它的对象凭空创建了一个全新的词法作用域。
funciton 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被泄露到全局作用域上了