songStar0904/You-don-t-know-JavaScript

第一部分 作用域和闭包 第二章 ----词法作用域

Opened this issue · 0 comments

2.1 词法阶段

大部分标准语言编译器的第一个工作阶段叫做词法化。
词法作用域就是定义在词法阶段的作用域,换句话说,是由你在写代码时将变量和块作用域写在哪里决定的,因此当词法分析器处理代码时会保持作用域不变。

// 包含整个全局作用域 其中有一个标识符:foo
function foo(a){
  // 包含foo所创建的作用域, 其中有三个标识符: a, bar, b
  var b = a * 2;
  function bar(c){
    // 包含bar所创建的作用域, 其中只有一个表示服: c
    console,log(a, b, c);
  }
  bar(b * 3);
}
foo(2); // 2, 4, 12

查找
引擎执行的时候, 首先从最内层的作用域开始查找, 如果没找到会向外层查找, 直到全局作用域。优先级是内层要大于外层, 也就是找到了就取值, 不再查找, 如果全局作用域还未找到则会报错。

2.2 欺骗词法

也就是改变原来词法作用域。有两种机制:evalwith 。但是切记欺骗词法作用域会导致性能下降, 因此,在严格模式下, 这两个被禁止所用。千万别用!
2.21 eval

function foo(str, a){
  eval(str); // 欺骗!!
  console.log(a, b);
}
var b = 2;
foo('var b = 3;', 1); // 1, 3

而且eval他能让字符串执行js语句, 还会导致你的js极其的不安全
2.22 with

function foo(obj){
  with(obj){
    a = 2;
  }
}
var o1 = {
  a: 3
};
var o2 = {
  b: 3;
}
foo(o1);
console.log(o1.a); // 2
foo(o2);
console.log(o2.a); // undefined
console.log(a); // 2 不好,a被泄露到全局作用域上了!