我正在研究简单的克隆功能
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]
有人可以告诉我为什么这些物体的行为不同吗? 这种行为将来会改变吗?
谢谢。
答案 0 :(得分:1)
您演示的行为与对象的[[Class]]
无关。
如果您记录Map.prototype
,您会发现这些新类型有toStringTag
Symbol:
> Map.prototype
Map {Symbol(Symbol.toStringTag): "Map"}
此Symbol属性的值用于生成toString()
生成的字符串。见Symbol.toStringTag
on MDN:
用于对象的默认描述的字符串值。由Object.prototype.toString()使用。
我怀疑为了向后兼容性,这种行为会因ES6之前的类型而改变。
答案 1 :(得分:0)
该对象不是一组。真实集具有内部[[SetData]]插槽,您无法复制。
shallowCopy(new Set()).add(123); // TypeError: add method called on incompatible Object
基本上,不要相信[[Class]]知道你拥有哪种对象。嗯,实际上[[Class]]已经在ES6中被核化并且不再存在。
答案 2 :(得分:0)
规范定义了在构造名为@@toStringTag
的对象的字符串表示期间使用的特殊符号。请参阅Well-Known Symbols部分,特别是将 @@ toStringTag 描述为
字符串值属性,用于创建对象的默认字符串描述。通过内置方法Object.prototype.toString访问。
现在,如果您为这些类型检查 @@ toStringTag 的值,例如Set:
23.2.3.12 Set.prototype [@@ toStringTag]
@@ toStringTag属性的初始值是字符串值“Set”。