1.eval
function foo(str, a){
eval(str)
console.log(a,b);
}
var b = 2;
foo('var b = 3', 1)
“var b = 3 ” 会被当做本来就在那里一样来处理。由于那段代码声明了变量b。因此它对已经存在的foo(..)的词法作用域进行了修改。
eval()可以在运行期修改书写期的词法作用域
setTimeout() setInterval(),new function() 类似
2.with


将o1传递进去,a=2赋值操作找到了o1.a并将2赋值给他。当o2传递进去,o2并没有该属性,因此不会创建这个属性。o2.a保持undefined.
with 可以将一个没有或有多个属性的对象处理为一个完全隔离的词法作用域,因此这个对象的属性也会被处理为定义在这个作用域中的词法标识符。但是这个块内部正常的var声明并不会被限制在这个块的作用域中,而是被添加到with所处的函数作用域中。严格模式禁用with。
3.eval和with影响性能
js引擎在编译阶段进行数项的性能优化。其中有些优化依赖于能够根据代码的词法进行静态分析,并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。如果引擎中出现了eval和with。只能简单的假设关于标识符位置的判断都是无效的,因为无法在词法分析阶段明确知道eval()会接受什么代码。
js引擎无法在编译时对作用域查找进行优化
网友评论