乐趣区

关于javascript:精读JS-with-语法

with 是一个不举荐应用的语法,因为它的作用是扭转上下文,而上下文环境对开发者影响很大。

本周通过 JavaScript’s Forgotten Keyword (with) 这篇文章介绍一下 with 的性能。

概述

上面是一种应用 with 的例子:

with (console) {log('I dont need the"console."part anymore!');
}

咱们往上下文注入了 console 对象,而 console.log 这个属性就被注册到了这个 Scope 里。

再比方:

with (console) {with (['a', 'b', 'c']) {log(join('')); // writes"abc" to the console.
  }
}

通过嵌套,咱们能够追加注入上下文。其中 with (['a', 'b', 'c']) 其实是把 ['a', 'b', 'c'] 的返回值对象注入到了上下文,而数组对象具备 .join 成员函数,所以能够间接调用 join('') 输入 "abc"

为了不让后果这么 Magic,倡议以枚举形式申明要注入的 key:

with ({myProperty: 'Hello world!'}) {console.log(myProperty); // Logs "Hello world!"
}

那为什么不举荐应用 with 呢?比方上面的状况:

function getAverage(min, max) {with (Math) {return round((min + max) / 2);
  }
}

getAverage(1, 5);

注入的上下文可能与已有上下文产生抵触,导致输入后果为 NaN

所以业务代码中不举荐应用 with,而且实际上在 严格模式 下 with 也是被禁用的。

精读

因为 with 定义的上下文会优先查找,因而在前端沙盒畛域是一种解决方案,具体做法是:

const sandboxCode = `with(scope) {${code} }`
new Function('scope', sandboxCode)

这样就把所有 scope 定义的对象限定住了。但如果拜访 scope 外的对象还是会向上冒泡查找,咱们能够联合 Proxy 来限度查找范畴,这样就能实现一个可用性尚可的沙盒。

第二种 with 的用法是前端模版引擎。

咱们常常看到模版引擎里会有一些 forEachmap 等非凡用法,这些语法齐全能够通过 with 注入。当然并不是所有模版引擎都是这么实现的,还有另一种计划是,现将模版引擎解析为 AST,再依据 AST 结构并执行,如果把这个过程放到编译时,那么 JSX 就是一个例子。

最初对于 with 注入上下文,还有一个误区,那就是认为上面的代码仅仅注入了 run 属性:

with ({run: () => {}}) {run()
}

其实不然,因为 with 会在整个原型链上查找,而 {} 的原型链是 Object.prototype,这就导致挂在了许多非预期的属性。

如果想要挂载一个污浊的对象,能够应用 Object.create() 创建对象挂载到 with 上。

总结

with 的应用场景很少,个别状况下不举荐应用。

如果你还有其余正经的 with 应用场景,能够告知我,或者给出评论。

探讨地址是:精读《JS with 语法》· Issue #343 · dt-fe/weekly

如果你想参加探讨,请 点击这里,每周都有新的主题,周末或周一公布。前端精读 – 帮你筛选靠谱的内容。

关注 前端精读微信公众号

<img width=200 src=”https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg”>

版权申明:自在转载 - 非商用 - 非衍生 - 放弃署名(创意共享 3.0 许可证)

退出移动版