摘要:学习 with 的用法,不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源
作用
with 语句可以扩展一个语句的作用域链,会将某个对象添加到作用域链的顶部
语法
1 | with (expression) { |
expression:将给定的表达式添加到在评估语句时使用的作用域链上
statement:执行语句。如果在 statement 中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,JavaScript 通过作用域链查找时会将这个变量指向这个属性值。如果没有同名的属性,则将拋出 ReferenceError 异常
注意:不推荐使用 with,在 ECMAScript 5 严格模式中该标签已被禁止,替代方案是使用一个临时变量来承载所需要的属性
示例:
1 | var a, x, y; |
弊端
使用 with 虽然可以减少不必要的指针路径解析运算,用起来很方便,但有很多弊端:
1、降低性能。with 语句使得程序在查找变量值时,都是先在指定的对象中查找,JS引擎无法对这段代码进行优化
2、内存泄漏。在非严格模式下,with 语句在没有找到对应变量的时候,会自动在全局作用域创建一个全局变量。例如:
1 | var a = { |
3、语义不明,难以维护。例如下面代码,很容易疏忽遗忘而造成传入函数 print 的 x 要用函数 f 的参数值,还是对象 o 的 x 属性值
1 | function f(x, o) { |
4、无法向前兼容。例如使用原生数据类型的时候:
1 | function f(foo, values) { |
在 ECMAScript 5的环境下,with 中的 values 指向传入函数 f 的第二个参数。但是在 ECMAScript 6环境下,Array.prototype 添加了一个 values 方法,values 指向的是 [1,2,3].values