克隆JavaScript对象 - 包括Getters和Setter

时间:2015-12-27 13:35:26

标签: javascript javascript-objects

在我正在进行的项目中,我不得不将对象克隆到变量。
我第一次尝试 - 似乎是最明显的解决方案 - 做var obj2 = obj1,但我很快意识到这使得obj2 引用到obj1,所以每当我在obj2中设置属性时,属性也在obj1中更新。好吧,我不能那样做。所以,我开始寻找在JavaScript中克隆对象的方法 - 我找到了多种解决方案,主要是 var obj2 = JSON.parse(JSON.stringify(obj1)) - 但这并没有保留我为对象定义的所有吸气剂和制定者!
对我来说,现在最明显的解决方案似乎首先使用上面的JSON技巧使obj2具有所有obj1的属性,然后循环遍历所有对象getter和setter并使用Object.defineProperty()添加它们,但是我还没有找到一种方法来获取对象的所有getter / setter。

2 个答案:

答案 0 :(得分:19)

在实际层面上,100%准确克隆对象是不可能的,因为getter和setter(实际上是其他函数)可能通过闭包访问词法范围的私有变量。访问这样的方法将引用原始对象,而不是克隆。

如果(且仅当)不是这种情况,您可以枚举通过Object.getOwnPropertyNames()找到的所有属性(甚至是不可枚举的属性),然后为每个名称简单地获取个人{{ 1}}使用PropertyDescriptors,然后将结果字段传递给Object.getOwnPropertyDescriptor,例如:

Object.defineProperty

在ES2017中,您可以do this instead

function shallowClone(obj) {
    var clone = Object.create(Object.getPrototypeOf(obj));

    var props = Object.getOwnPropertyNames(obj);
    props.forEach(function(key) {
        var desc = Object.getOwnPropertyDescriptor(obj, key);
        Object.defineProperty(clone, key, desc);
    });

    return clone;
}

答案 1 :(得分:0)

通过@Alnitak,我认为这是快捷方式

function shallowClone(obj){
 var clone = Object.create(Object.getPrototypeOf(obj));
 var descriptors = Object.getOwnPropertyDescriptors(obj);
 Object.defineProperties(clone, descriptors);
 return clone;
}