词法作用域 - 1

  1. 词法阶段
    1. 词法化
      1. 对源代码中的字符进行检查
    2. 词法作用域
      1. 就是写代码时将变量和块作用域写在哪里决定
    3. 作用域查找会在找到第一个匹配的标识符时停止
      1. 所以,重名标识符会有overriding
    4. 作用域始终从运行时所处的最内部作用域开始
      1. 逐级向外,沿着作用域链
    5. 综上,运行时,在最内部作用域开始搜寻变量,找不到沿着作用域链向外查找,找到第一个与之匹配的标识符,OK
  2. 改变词法作用域
    1. eval
      • function foo(str, a) {    
             eval(str);    
             console.log(a, b);    
         }
        
         var b = 2;
         foo("var b = 3;", 1);    // 1, 3
    2. 严格模式下的eval没有效果
      • function foo(str) {
            "use strict";
            eval( str );
            console.log( a );    // ReferenceError: a is not defined
        }
        foo( "var a = 2" );
      • 严格模式下,eval在运行时有自己的词法作用域
    3. eval(..)可以将包含声明语句的代码字符串插入,修改运行时的词法作用域
      1. with
    4. var obj = {
          a: 2,
          b: 3
      };
      
      function fo(obj) {
          with (obj) {
              b  = 5;
          }
      }
      
      var o = {
          b: 33
      };
      
      var p = {
          a: 23
      };
      
      fo(o);
      console.log(o.b);    // 5
      
      fo(p);
      console.log(p.b);    // undefined
    5. 对象o有属性;,对象p没有属性b,不会创建该属性
    6. with语句将一个对象的引用作为作用域来处理,将对象的属性当作作用域中的标识符,创建了一个新的运行时词法作用域
      1. eval和with使引擎在编译时对作用域的优化无效,所以会导致运行变慢。

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