Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Defining a utility function to inspect objects' prototype chains (in Chrome), I get this for arrays.

array prototype chain

So it would appear that

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

I understand the first equality. I have no idea what the third term is, though I have heard that ES6 will have Symbols.

Is this thing the same as Array.prototype? Why does it print that way?

Edit: chrome://version information:

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
like image 625
spelufo Avatar asked Mar 22 '15 14:03

spelufo


1 Answers

Comment on 2014-04-14

It seems Chrome's console.log print all Symbol-type-keys, here is an example:

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

which prints:

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

I don't why chrome behaves this way, is it for debugging or something else?

Fotunately it does not affect the toString() result so all code is safe.


It seems console.log would especially print the Symbol.unscopable key in console, we can have a plain object to perform like this:

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

which outputs:

Object {Symbol(Symbol.unscopables): Object}

The Symbol.unscopables symbol is a special symbol defined in ES6 as @@unscopables which is used for excluding some properties when this object works in a with environment, the official explanation is:

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

A simple example:

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
}

You can use Array.prototype[Symbol.unscopables] to find all keys which cannot be used in with environment

However still, the output of a Array.prototype is not exactly the same as a plain object with Symbol.unscopables key, it outputs [Symbol(Symbol.unscopables): Object], which is a format more like an array

I can't exactly explain why, this may be related to the Symbol.toStringTag which controls how an object should be formatted to string, but Chrome currently does not export this symbol so it's hard to test

like image 187
otakustay Avatar answered Oct 17 '22 03:10

otakustay