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
据我了解,一种获得与阅读值(value)有关,另一种与分配有关。
a--
应该写入读取a
的同一位置,这是合乎逻辑的。不,这不对。但是获得
Symbol.unscopables
的值(value)两次暗示了我们,可以传递一个对象进行读取,而传递另一个对象进行写入。这样工作真的是真的吗?规范说明了什么?
实际上,它几乎可以在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
最佳答案
按照规范,对于@x++,@@ unscopables应该只能读取一次,据我所知。查看https://mail.mozilla.org/pipermail/es-discuss/2017-February/047725.html中的详细信息
因此,Chrome和Firefox在这里都是错误的。 Safari正确无误。
另请参见https://bugzilla.mozilla.org/show_bug.cgi?id=1341061和https://bugs.chromium.org/p/v8/issues/detail?id=5992