你不知道的Javascript上卷 - 读书笔记 - 第2章词法作用域-2.2 欺骗词法
- 作用域
- `eval`和`with`的缺点
作用域
Javascript
在ES6
以前只有函数作用域
。ES6
开始支持块作用域
: 通常就是 {} 包裹的范围- 作用域中查找变量or函数的规则是从当前向上(父集)逐级查找,找到最近的就拿来用。
- 如果找到顶级(全局作用域:比如浏览器的window对象)还没有,就默认创建一个。
- 词法作用域的规则决定,所有变量or函数在写代码时就已经确定了他所在的作用域。但是也有动态修改词法作用域的情况比如
eval
和with
。 - 这两东西都不推荐使用了。但是作为学习理解还是有点用的。
eval
和
with
的缺点
- 最直接的就是,有他们的存在使代码变的不确定,所以
JS引擎
就放弃对这段代码的优化。这导致性能低下。 eval
另一个显著的问题就是如果执行的字符串来自外部,很可能存在注入的风险。with
还可能导致意外的修改上级作用域变量。例如下面代码就意外导致创建了一个全局变量 b
。这种非预期的行为,会导致我们被莫名的BUG折磨致死。(除非创建全局变量 b
就是你想要的结果,但是你也应该选择一个可读性更高的方案来实现)
function test(obj){with(obj){a = 1;b = 2;}
}
var obj = {a:0};
test(obj);
console.log(obj);
console.log(b);