[].__proto__ === Array.prototype // === [符号(Symbol.unscopables): 对象]?

[].__proto__ === Array.prototype // === [Symbol(Symbol.unscopables): Object]?

定义一个实用函数来检查对象的原型链(在 Chrome 中),我得到了数组。

所以看起来

[].__proto__ === Array.prototype  // === [Symbol(Symbol.unscopables): Object] 

我理解第一个相等。我不知道第三项是什么,虽然我听说 ES6 会有 Symbols。

这个东西和Array.prototype一样吗?为什么会这样打印?

编辑:chrome://版本信息:

Google Chrome   40.0.2214.111 (Official Build) 
Revision    6f7d3278c39ba2de437c55ae7e380c6b3641e94e-refs/branch-heads/2214@{#480}
OS  Linux 
Blink   537.36 (@189455)
JavaScript  V8 3.30.33.16

评论于 2014-04-14

似乎 Chrome 的 console.log 打印了所有 Symbol-type-keys,这里是一个例子:

var o = {};
o[Symbol.iterator] = function () {};
o[Symbol.unscopables] = {};
var s = Symbol('s');
o[s] = 3;
console.log(o);

打印:

Object {Symbol(Symbol.unscopables): Object, Symbol(Symbol.iterator): function, Symbol(s): 3}

我不明白为什么 chrome 会这样,是为了调试还是其他原因?

幸运的是,它不会影响 toString() 结果,因此所有代码都是安全的。


似乎console.log会在控制台中特别打印Symbol.unscopable键,我们可以有一个普通的对象来执行这样的操作:

var o = {};
o[Symbol.unscopables] = {};
console.log(o);

输出:

Object {Symbol(Symbol.unscopables): Object}

Symbol.unscopables符号是ES6中定义的一个特殊符号@@unscopables,用于对象在with环境下工作时排除某些属性,官方解释为:

An object valued property whose own property names are property names that are excluded from the with environment bindings of the associated object.

一个简单的例子:

var o = {x: 1, y: 2};
o[Symbol.unscopables] = {
    y: true
};

console.log(o.x); // 1
console.log(o.y); // 2

with(o) {
    console.log(x); // 1
    console.log(y); // ReferenceError: y is not defined
}

您可以使用Array.prototype[Symbol.unscopables]找到所有不能在with环境下使用的密钥

然而,Array.prototype的输出与带有Symbol.unscopables键的普通对象并不完全相同,它输出[Symbol(Symbol.unscopables): Object],这是一种更像数组的格式

我无法准确解释原因,这可能与控制对象应如何格式化为字符串的 Symbol.toStringTag 有关,但 Chrome 目前不导出此符号,因此很难测试