本文章引用《你所不知道的Javascript》
代码如下:
(1)eval
function foo(str,a){eval(str);console.log(a,b);} var b = 2; foo("var b=3;",1);
运行结果如下:1 3
以上代码,eval()通过动态创建代码修改作用域,从而改变了b的作用域。
通过以上例子,我们可以发现一些动态创建代码的方法
setTimeout(),setInterval()的第一个参数可以是字符串。
new Function(),第一个参数作为创建代码的形参,稍微安全些。
由于动态生成代码生成的场景罕见,所以无法抵消洗性能上的损耗。
(2)with
with是重复引用同一个对象中多个属性的快捷方式,可以不需要重复引用对象本身。
代码
function foo(obj){with(obj){a =2}} var o1 = {a:3}; var o2={b:3};foo(o1); console.log(o1.a);console.log(o2.a) console.log(a)
运行结果
2 undefined 2(被全局引用了)
运行结果前两个代表当前作用域里是否包含此属性。最后查找a的作用域的时候,全局查找执行到a=2,就自动创建了一个全局变量。
总结:
通过以上两种欺骗词法我们可以看出,eval和with都可以间接改变一些字段的作用域。严格模式下,禁止使用这两种方式。
那为什么会影响性能呢?
解释如下:
Javascript 引擎会在编译阶段进行熟项的性能优化,比如:对词法进行静态分析,确定所有变量和函数定义的位置。
可以看出eval,with对于以上定义是无效的,同时也无法确定作用域是什么。所以运行会变得很慢。------不要使用它们