克隆:什么是JSON.parse(JSON.stringify(x))的最快替代品?

fad*_*bee 31 javascript

什么是最快的替代品

JSON.parse(JSON.stringify(x))
Run Code Online (Sandbox Code Playgroud)

必须有一个更好/内置的方法来对对象/数组执行深度克隆,但我还没有找到它.

有任何想法吗?

Ray*_*nos 16

不,没有构建深度克隆对象的方法.

深度克隆是一个难以处理的问题.

让我们假设一个方法deepClone(a)应该返回b的"深度克隆".

现在,"深度克隆"是一个具有相同[[Prototype]]的对象,并且克隆了所有自己的属性.

对于克隆过的每个clone属性,如果它具有可以克隆的属性,则以递归方式执行此操作.

当然是保持元数据附加到[[Writable]]和[[Enumerable]]等属性.如果它不是一个对象,我们将返回该东西.

var deepClone = function (obj) {
    try {
        var names = Object.getOwnPropertyNames(obj);
    } catch (e) {
        if (e.message.indexOf("not an object") > -1) {
            // is not object
            return obj;
        }    
    }
    var proto = Object.getPrototypeOf(obj);
    var clone = Object.create(proto);
    names.forEach(function (name) {
        var pd = Object.getOwnPropertyDescriptor(obj, name);
        if (pd.value) {
            pd.value = deepClone(pd.value);
        }
        Object.defineProperty(clone, name, pd);
    });
    return clone;
};
Run Code Online (Sandbox Code Playgroud)

对于许多边缘情况,这将失败.

实例

正如您所看到的,在不破坏其特殊属性(如.length数组)的情况下,您无法深入克隆对象.要解决这个问题,你必须Array单独对待,然后单独处理每个特殊对象.

你做什么期望发生什么deepClone(document.getElementById("foobar"))

另外,浅克隆很容易.

Object.getOwnPropertyDescriptors = function (obj) {
    var ret = {};
    Object.getOwnPropertyNames(obj).forEach(function (name) {
        ret[name] = Object.getOwnPropertyDescriptor(obj, name);
    });
    return ret;
};

var shallowClone = function (obj) {
    return Object.create(
        Object.getPrototypeOf(obj),
        Object.getOwnPropertyDescriptors(obj)
    );
};
Run Code Online (Sandbox Code Playgroud)

  • @AndyE你为什么撒谎.日期有魔法[`console.log(Object.create(Date.prototype)); console.log(new Date());`](http://jsfiddle.net/BcNjU/5/) (2认同)

小智 10

2022 年的解决方案是使用 StructuredClone

请参阅:https ://developer.mozilla.org/en-US/docs/Web/API/structuredClone

structuredClone(x)
Run Code Online (Sandbox Code Playgroud)


Ale*_*leC 6

我实际上是将其与 angular.copy

您可以在此处运行JSperf测试:https ://jsperf.com/angular-copy-vs-json-parse-string

我正在比较:

myCopy = angular.copy(MyObject);
Run Code Online (Sandbox Code Playgroud)

myCopy = JSON.parse(JSON.stringify(MyObject));
Run Code Online (Sandbox Code Playgroud)

这是我可以在所有计算机上运行的所有测试中最糟糕的 在此处输入图片说明

  • 你们两个都叫亚历克斯(Alex),我很困惑,以为你在跟自己说话。 (13认同)