克隆对象没有参考javascript [英] Clone Object without reference javascript

查看:31
本文介绍了克隆对象没有参考javascript的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含大量数据的大对象.我想在其他变量中克隆它.当我设置实例 B 的一些参数在原始对象中具有相同的结果时:

I have a big object with much data. And i want to clone this in other variable. When i set some param of the instance B has the same result in the original object:

var obj = {a: 25, b: 50, c: 75};
var A = obj;
var B = obj;

A.a = 30;
B.a = 40;

alert(obj.a + " " + A.a + " " + B.a); // 40 40 40

我的输出应该是 25 30 40.有什么想法吗?

My output should be 25 30 40. Any ideas?

编辑

谢谢大家.我更改了dystroy的代码,这是我的结果:

Thanks Everyone. I change the code of dystroy and this is my result:

Object.prototype.clone = Array.prototype.clone = function()
{
    if (Object.prototype.toString.call(this) === '[object Array]')
    {
        var clone = [];
        for (var i=0; i<this.length; i++)
            clone[i] = this[i].clone();

        return clone;
    } 
    else if (typeof(this)=="object")
    {
        var clone = {};
        for (var prop in this)
            if (this.hasOwnProperty(prop))
                clone[prop] = this[prop].clone();

        return clone;
    }
    else
        return this;
}

var obj = {a: 25, b: 50, c: 75};
var A = obj.clone();
var B = obj.clone();
A.a = 30;
B.a = 40;
alert(obj.a + " " + A.a + " " + B.a);

var arr = [25, 50, 75];
var C = arr.clone();
var D = arr.clone();
C[0] = 30;
D[0] = 40;
alert(arr[0] + " " + C[0] + " " + D[0]);

推荐答案

如果您使用 = 语句将值分配给带有右侧对象的 var一边,javascript 不会复制而是引用对象.

If you use an = statement to assign a value to a var with an object on the right side, javascript will not copy but reference the object.

剧透:使用 JSON.parse(JSON.stringify(obj)) 可能有效但代价高昂,并且可能会抛出 TypeError,如

Spoiler : using JSON.parse(JSON.stringify(obj)) may work but is costly, and might throw a TypeError as in

const a = {};
const b = { a };
a.b = b;
const clone = JSON.parse(JSON.stringify(a));
/* Throws
Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'b' -> object with constructor 'Object'
    --- property 'a' closes the circle
    at JSON.stringify (<anonymous>)
    at <anonymous>:4:6
*/

从 es2015 开始,如果你想要一个浅拷贝(克隆对象,但在内部结构中保留深层引用),你可以使用解构:

As of es2015, if you want a shallow copy (clone the object, but keeping deep refences in the inner structure) you can use destructuring :

const obj = { foo: { bar: "baz" } };
const shallowClone = { ...obj };

shallowClone 是一个新对象,但 shallowClone.foo 持有对与 obj.foo 相同的对象的引用.

shallowClone is a new object, but shallowClone.foo holds a reference to the same object as obj.foo.

您可以使用 lodashclone 方法,如果您无权访问扩展运算符.

You can use lodash's clone method, which does the same, if you don't have access to the spread operator.

var obj = {a: 25, b: 50, c: 75};
var A = _.clone(obj);

或者 lodashcloneDeep 方法(如果您的对象有多个对象级别)

Or lodash's cloneDeep method if your object has multiple object levels

var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.cloneDeep(obj);

或者 lodashmerge 方法,如果你想扩展源对象

Or lodash's merge method if you mean to extend the source object

var obj = {a: 25, b: {a: 1, b: 2}, c: 75};
var A = _.merge({}, obj, {newkey: "newvalue"});

或者你可以使用jQuery的extend方法:

Or you can use jQuerys extend method:

var obj = {a: 25, b: 50, c: 75};
var A = $.extend(true,{},obj);

这是 jQuery 1.11 扩展方法的源代码:

Here is jQuery 1.11 extend method's source code :

jQuery.extend = jQuery.fn.extend = function() {
    var src, copyIsArray, copy, name, options, clone,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    if ( typeof target === "boolean" ) {
        deep = target;

        // skip the boolean and the target
        target = arguments[ i ] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
        target = {};
    }

    // extend jQuery itself if only one argument is passed
    if ( i === length ) {
        target = this;
        i--;
    }

    for ( ; i < length; i++ ) {
        // Only deal with non-null/undefined values
        if ( (options = arguments[ i ]) != null ) {
            // Extend the base object
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we're merging plain objects or arrays
                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && jQuery.isArray(src) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject(src) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don't bring in undefined values
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

var item ={ 'a': 1, 'b': 2}
Object.assign({}, item);

这篇关于克隆对象没有参考javascript的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆