2016-07-02 2 views
2

Я работаю на простой функции клона[[класс]] недвижимость в ES2015

var shallowCopy = function (value) { 
    // in ES2017 we can use 
    // return Object.create(Object.getPrototypeOf(value), Object.getOwnPropertyDescriptors(value)); 
    let propDescriptors = {}; 
    for (let i of Object.getOwnPropertyNames(value)) { 
    propDescriptors[i] = Object.getOwnPropertyDescriptor(value, i); 
    } 
    return Object.create(Object.getPrototypeOf(value), propDescriptors); 
}; 

Я понимаю, это поведение, которое Object.prototype.toString.call(shallowCopy([])) является [object Object], не [object Array].

Но некоторые новые типы в ES6 хорошо выглядеть

Object.prototype.toString.call(shallowCopy(new Set())) // [object Set] 
Object.prototype.toString.call(shallowCopy(new Map())) // [object Map] 

Может кто-нибудь сказать мне, почему эти объекты ведут себя по-разному?
Будет ли изменено это поведение в будущем?

спасибо.

+1

Там нет [[класс]] поле в ES6 больше, [ 'Object.prototype.toString' ] (http://www.ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) работает сейчас – Bergi

ответ

0

Спецификация определяет специальный символ, используемый при построении строкового представления объекта с именем @@toStringTag. См Well-Known Symbols раздела, в частности, он описывает @@ toStringTag в

ценного свойство Строки, которая используется при создании описания строки по умолчанию объекта. Доступ к встроенному методу Object.prototype.toString.

Теперь, если вы проверяете значения @@ toStringTag для этих типов, например, для Set:

23.2.3.12 Set.prototype [@@ toStringTag]

начальное значение свойства @@ toStringTag - это значение строки «Установить».

Не стесняйтесь проверить другие типы, как Promise (25.4.5.4), ArrayBuffer (24.1.4.4) и т.д.

1

Поведение, которое вы продемонстрировали, не связано с [[Class]] объекта.

При входе Map.prototype вы увидите, что эти новые типы имеют toStringTag Symbol:

> Map.prototype 
Map {Symbol(Symbol.toStringTag): "Map"} 

Значение этого свойства Символ используется при формировании строки, полученной путем toString(). См. Symbol.toStringTag on MDN:

Строковое значение, используемое для описания объекта по умолчанию. Используется Object.prototype.toString().

Я сомневаюсь, что это поведение изменится для типов до ES6, для обратной совместимости.

0

Объект не является комплектом. У реальных наборов есть внутренние [[SetData]] слоты, которые вы не можете реплицировать.

shallowCopy(new Set()).add(123); // TypeError: add method called on incompatible Object 

В принципе, не доверяйте [[Класс]], чтобы узнать, какой у вас объект. Ну, на самом деле [[Класс]] был задействован в ES6 и больше не существует.

Смежные вопросы