注意
with
语句已被弃用。但基本上所有浏览器都还支持它。
为什么还要使用with
语法?
我们在vue的template中写属性时,是无需指定对象this
的,vue解析template的时候就用了with
语法。
怎么使用的?
const obj = {
name: 'jason',
age: 25
};
with (obj) {
console.log(name, age);
}
with语法的作用
基本上,可以从上面例子可以看出with语法的作用。
官方的说明是:with
语句扩展一个语句的作用域链。
描述
js查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的context或者包含这个变量的函数有关。
with
语句将某个对象添加到作用域链的顶部,如果with
语句中有某个未使用命名空间的变量,跟作用域链的某个属性同名,则这个变量指向这个属性值。
严格模式下无法使用
我们写vue代码,都是在严格模式下的,那么vue是如何在严格模式下执行with
语句的呢?
结合Function()
构造函数
可以通过new Function()
创建函数,该函数仅在全局作用域中执行。
将with
语句放在new Function()
创建的函数体中。
const obj = {
name: 'jason',
age: 25
};
const fn = new Function(`
with (obj) {
console.log(name, age);
}
`);
console.log(fn());
使用with
语法的利弊
肯定是因为弊端更多,所以被废弃。
利
可以在不造成性能损失的情况下,减少变量的长度。造成的附加计算量很少。
弊
-
使得程序在查找变量值时,都是先在指定的对象中查找。所以那些本来不是这个对象的属性的变量,查找起来会很慢。若是对性能要求较高的场合,
with
语句中的变量只应该包含这个指定对象的属性(同vue的template)。 -
不易阅读
function f(x, o) {
// 不能确定x是o的属性,还是入参x。
with (o) print(x);
}
- 无法向前兼容
// 若foo是一个数组,在es5环境下,数组是没有values属性的,所以with内部的values是入参values。
// rs6环境下,数组具有values属性,with内部的values指向数组的属性。
function f(foo, values) {
with (foo) {
console.log(values);
}
}