【问题标题】:Why does browser get Symbol.unscopables twice?为什么浏览器会两次获得 Symbol.unscopables?
【发布时间】:2017-03-28 11:34:52
【问题描述】:

with(new Proxy({}, {
  has() { return true },
  get(obj, key, proxy) { return console.log(String(key)) } })
) {
  a--
}

Chrome 中的输出:

Symbol(Symbol.unscopables)
a
Symbol(Symbol.unscopables)

Firefox 中的输出:

Symbol(Symbol.unscopables)
Symbol(Symbol.unscopables)
a

据我了解,一个获得与阅读价值有关,另一个与分配有关。

a-- 应该写入读取 a 的相同位置是合乎逻辑的。 不,不是。

但是两次获得Symbol.unscopables 的值向我们暗示,可以将一个对象传递给读,另一个传递给写。

真的是这样工作的吗?规范是怎么说的?

实际上,它几乎可以在 Chrome 和 FF 中工作 - 可以从一个对象读取并写入另一个对象,但会导致不同的结果:

更新:Safari 10 只读取一次。

var a, b, flag = true

with (a = { x: 7 })
  with (b = { x: 4, get [Symbol.unscopables]() { return { x: flag=!flag } } })
    x++

                 // Chrome   FF       Safari   Edge
console.log(a)   // {x:5}    {x:7}    {x:7}    {x:5}
console.log(b)   // {x:4}    {x:8}    {x:5}    {x:4}

PS:Same question in Russian

【问题讨论】:

  • 你为什么要混合with 和现代功能? with 不会出现在惯用的 JS 中。
  • @ssube,你甚至可以问我为什么要动态更改unscopables,但我只是对它应该如何工作感兴趣。没有任何现实生活中的例子。也许只是在某个地方进行代码高尔夫比赛:)
  • @Gothdo,它与代理无关。代理只是明确显示,该值被采用了两次。但后面的示例无需任何代理即可工作。
  • 那将是后续行动,但如果这是为了科学,请继续,祝你好运。 ;) 请不要在现实生活中使用with
  • @guest271314, FF48+ is required.

标签: javascript ecmascript-6 with-statement


【解决方案1】:

据我所知,对于“x++”,@@unscopables 应该只读取一次。详情见https://mail.mozilla.org/pipermail/es-discuss/2017-February/047725.html

因此,Chrome 和 Firefox 都存在缺陷。 Safari 做到了这一点。

另见https://bugzilla.mozilla.org/show_bug.cgi?id=1341061https://bugs.chromium.org/p/v8/issues/detail?id=5992

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2017-01-04
    • 1970-01-01
    • 2011-05-20
    • 1970-01-01
    • 2014-12-18
    相关资源
    最近更新 更多