我需要编写一个返回对象克隆的函数。
类似的东西:
// non recursive clone
function clone( obj ) {
const newObj = Object.create( Object.getPrototypeOf(obj) );
return Object.assign( newObj, obj );
}
这当然只适用于对象,而不适用于原始类型:它不适用于undefined
,null
,布尔值,数字,字符串,符号。
...但它也不适用于其他类型,例如Array
,Set
,Map
。
我想支持尽可能多的类型,我对如何执行此操作的最佳想法是逐个处理特殊类型。
我认为Internal Methods or Internal Slots的对象可能会产生问题。我不完全确定这一点,我找不到内部方法或插槽的标准类型列表。
Object.create()
无法正确创建哪些标准类型?
答案 0 :(得分:1)
Object.create()
无法正确创建哪些标准类型?
所有这些,的确如此。您谈论的那些特殊类型只能使用new
或Reflect.construct
创建,提供将创建内部插槽的内置构造函数。
我找不到包含内部方法或老虎机的标准类型列表。
它就在规范chapter 9 Exotic Objects中(对于内部方法)。你可以很好地处理ordingary对象(Object.create
创建一个),但是你会遇到Function对象,Bound Function对象,Array对象,String对象,Arguments对象,TypedArray对象,Module命名空间对象和Proxies的问题。此外,您可以通过搜索 OrdinaryCreateFromConstructor (Generator
,Boolean
,Error
以及所有其他本机错误{{{}的用法来查找具有特殊内部插槽的对象1}},Number
,Date
,RegExp
,Map
,Set
,WeakMap
,WeaskSet
,{{1} },ArrayBuffer
)和 ObjectCreate (DataView
,Promise
,所有类型数组,ListIterator
,Arguments
,{{1} },StringIterator
)。
我想支持尽可能多的类型
您应该决定(并记录)哪些是受支持的,哪些不受支持。特别是对于递归克隆,这将是一个麻烦。还要确保记录如何处理不可枚举或符号键控的自有属性和getter / setter,默认的ArrayIterator
行为可能不是所需的行为。
如何做到这一点是逐个处理特殊类型?
我在所有支持的类型的原型上定义了一个MapIterator
方法,这样很容易扩展。可能使用已知值而不是支持克隆和/或默认复制算法没有意义,例如,在迭代器或函数对象上,以便可以使用错误消息处理它们或忽略它们。