我们了解到作用域是在语法分析的时候就决定了的,那么我们要怎么才能"动态的改变作用域呢?"
----------->eval()
一个简单的实例
function foo(a){
eval("var b=1");
console.log(a+b); //4
}
foo(3);
可以看到我们在foo()函数中和全局函数中,我们都没有声明变量b,而程序却没有ReferenceError错误,就说明
我们使用eval();动态的生成了变量b,也就是改变了作用域,当然这个只是在非严模式的情况下才能执行的
在看一个例子
function foo(a){
"use strict";//在这里使用严模式
eval("var b=1");
console.log(a+b); //这里就会报错
}
foo(3);
----------->with(变量)
var o1={
a:3
};
var o2={
b:2
};
function foo(obj){
with(obj){//将obj绑定到一个词法作用域
a=4;
}
}
foo(o1);
console.log(o1.a);//4
foo(o2);
console.log(o2.a);//undefine
console.log(a);//4
这个例子说明了a在严模式下泄露到了全局作用域中!!!
最后:
JavaScript 中有两个机制可以“欺骗”词法作用域: eval(..) 和 with 。前者可以对一段包
含一个或多个声明的“代码”字符串进行演算,并借此来修改已经存在的词法作用域(在
运行时)。后者本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作
用域中的标识符来处理,从而创建了一个新的词法作用域(同样是在运行时)。
这两个机制的副作用是引擎无法在编译时对作用域查找进行优化,因为引擎只能谨慎地认
为这样的优化是无效的。使用这其中任何一个机制都将导致代码运行变慢。不要使用它们。