javascript - 如何在 JavaScript 中创建完全独立的对象实例

标签 javascript

如何在 JavaScript 中创建一个不影响该对象的任何其他实例的对象实例,下面是一个示例:

var A = {
        b: "2", 
        c: "3", 
        d: {
            e: "5", 
            f:{
                    g: "7"
                },
            h: function(){
               return "8";
              }
            }
}
var a1 = Object.create(A);
var a2 = Object.create(A);
a1.d.f.g = 10;
console.log(a2.d.f.g);//Result is 10 while it was supposed to be 7

在上面的例子中,当a1.d.f.g时已更改,a2.d.f.g也被改变了。怎么了?

我什至尝试过Object.assign({}, A) ,但问题仍然存在。

var a1 = Object.assign({}, A);
var a2 = Object.assign({}, A);

更新: 感谢一些给我线索的答案,经过大量搜索后,我发现 JavaScript 中有两个与对象复制相关的概念,Shallow CopyDeep Copy ,在浅复制中,仅复制顶层属性,但将共享更高级别的引用对象属性,如果您想要一个完全独立的实例,则需要深复制或深克隆。

A shallow copy successfully copies primitive types like numbers and strings, but any object reference will not be recursively copied, but instead the new, copied object will reference the same object.

If an object references other objects, when performing a shallow copy of the object, you copy the references to the external objects.

When performing a deep copy, those external objects are copied as well, so the new, cloned object is completely independent from the old one. Source

我个人认为 JavaScript 中的浅拷贝和深拷贝概念看起来很奇怪,没有意义,但它就是这样,另外,有点 similar stuff C# 中也存在。 Object.assign()spread operator进行浅复制,因此您需要另一个函数来为您进行深克隆。

有些人建议使用 JSON.parse(JSON.stringify(obj))但它不适用于函数本身的属性,例如 a1.d.h()如果您使用 JSON 解决方案,上面示例中的内容无效,此外,在某些情况下,类型可能会发生变化,例如日期类型。

推荐一些库,但就我而言,我不想使用任何第三方。我发现最好使用循环引用对象属性并创建深度克隆,这是我正在讨论的方法:

function deepClone (obj) {
    var _out = new obj.constructor;

    var getType = function (n) {
        return Object.prototype.toString.call(n).slice(8, -1);
    }

    for (var _key in obj) {
        if (obj.hasOwnProperty(_key)) {
            _out[_key] = getType(obj[_key]) === 'Object' || getType(obj[_key]) === 'Array' ? deepClone(obj[_key]) : obj[_key];
        }
    }
    return _out;
}

所以最终会变成这样:

var a1 = deepClone(A);
var a2 = deepClone(A);
a1.d.f.g = 10;
console.log(a2.d.f.g);//Result is 7 now

最佳答案

您需要创建深度克隆,可以使用JSON.parse(JSON.stringify())进行深度克隆

var A = {
        b: "2", 
        c: "3", 
        d: {
            e: "5", 
            f:{
                    g: "7"
                }
            }
}
var a1 = JSON.parse(JSON.stringify(A));
var a2 = JSON.parse(JSON.stringify(A));
a1.d.f.g = 10;
console.log(a2.d.f.g);

关于javascript - 如何在 JavaScript 中创建完全独立的对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57016399/

相关文章:

javascript - 编写一个使用 .pop 和 .splice 旋转数组的函数

javascript - 如何将 MySQL 数据库连接到 ReactJS 应用程序?

javascript - 使用 Javascript 提交表单

javascript - 如何以这种方式比较 3 个值?

javascript - 转换为指令的 jQuery 函数在 Angular 上不起作用

javascript - 如何从 Backbone.js 中的集合中的另一个模型触发模型更新?

javascript - 如何为循环中的所有子节点分配特定属性

php - 尝试使用 mod_rewrite 获取通用的 php/javascript 库

javascript - Node.js Firestore 错误 - 无法编码值

javascript - 为什么这段 JavaScript 代码给我错误 "undefined"?