作用域--欺骗词法

本文章引用《你所不知道的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对于以上定义是无效的,同时也无法确定作用域是什么。所以运行会变得很慢。------不要使用它们

你可能感兴趣的:(作用域--欺骗词法)