动态作用域

我们了解到作用域是在语法分析的时候就决定了的,那么我们要怎么才能"动态的改变作用域呢?"

----------->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 。前者可以对一段包
      含一个或多个声明的“代码”字符串进行演算,并借此来修改已经存在的词法作用域(在
      运行时)。后者本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作
      用域中的标识符来处理,从而创建了一个新的词法作用域(同样是在运行时)。
      这两个机制的副作用是引擎无法在编译时对作用域查找进行优化,因为引擎只能谨慎地认
      为这样的优化是无效的。使用这其中任何一个机制都将导致代码运行变慢。不要使用它们。

Hold on, everything is possible.
原文地址:https://www.cnblogs.com/student-note/p/6632235.html