JavaScript里的with语句你知道吗?|8月更文挑战

711 阅读3分钟

最近看别人的代码的时候,发现用到了with语句,感觉实在陌生,查了一下文档,结果在文档上看到的第一句就是【不建议使用with语句,因为它可能是混淆错误和兼容性问题的根源】。虽然不建议使用,但感觉至少还是需要知道一下!

语法

expression:新的默认对象

statement:一个或多个语句 oject是该语句的默认对象

with (expression) {
    statement
}

with语句中查询变量顺序:

  ①、 是否是 with语句中的局部变量,如果不是则进行②

  ②、 是否是 expression中的变量,如果不是则进行③

  ③、 查找更高作用域范围.

使用

如以下示例:

原本使用js的一些数学函数,需要Math.PIMath.cos(x)Math.sin(x)等方式;

image.png

但当Mathwith语句指定为新的默认对象时,后续的所有引用都指向了Math对象,这样PI、cos、sin函数直接就能被使用,

image.png

简单的来说可以把with理解成一种速写方式,在指定的代码区域,通过节点名称就能调用对象。

之所以把【使用】放在【定义】之前,是因为实例比文字更容易理解。

定义

with语句用于:将代码的作用域设置到一个特定的作用域中。

方便用来引用某个对象中已有的属性但是不能用来给对象添加属性, 要给对象创建新的属性 必须明确的引用该对象。

如以下,即使在with里面给y赋值了,但是obj.y也还是undefined image.png

with的弊端

1、语义不明;

因为with语句会使得代码不易阅读,同时使得JavaScript编译器难以在作用域链上查找某个变量,难以决定应该在哪个对象上来取值。

2、性能问题;

JS引擎在执行代码之前有一个编译阶段,其中有些优化依赖于能够根据代码的词法进行静态分析,并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。

但是使用了with之后,引擎只能简单地假设关于标识符位置的判断都是无效的,因为无法知道传递给 with 用来创建新词法作用域的对象的内容到底是什么。所以js就不会优化。

如下示例

相同的代码,没有使用With只需要1s,使用之后竟需要9s。

image.png

『注意』

1、with会自动在全局作用域创建一个全局变量,在严格模式下,会抛出ReferenceError 异常。

2、with会在运行时修改或创建新的作用域,以此来欺骗其他在书写时定义的词法作用域。

3、with 语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多数情况下,如果可能,最好避免使用它。

4、使用with之后js压缩工具就无法对这段代码进行压缩,这也是影响性能的一个因素。

结语

虽然with有一大堆的缺点,但是还是需要知道一下的,不然岂不是淘宝首页第一句就看不懂了!😝 image.png

参考:
MDN Web Docs
理解javascript中的with关键字


小可爱看完点个赞再走吧!😗