当前位置: 移动技术网 > IT编程>开发语言>JavaScript > javascript 对象克隆

javascript 对象克隆

2019年01月19日  | 移动技术网IT编程  | 我要评论

浅克隆

先看代码:

/**
 * 浅克隆 克隆传入对象,只克隆一层
 * @param {any} source
 */
function shallowclone(source) {
    var tiaget = createectype(source);  //创建一个副本
    // 将原对象的所有属性值赋值到新对象上
    for (var property in source) {
        if (source.hasownproperty(property)) {
            tiaget[property] = source[property];
        }
    }
    /**
    * 创建副本
    * @param {any} source
    */
    function createectype(source) {
        var newobject = {};
        if (array.isarray(source))
            newobject = [];
        return newobject;
    }

    return tiaget;
}

执行测试:

 var a={a1:1,a2:2,a3:[1,2,3]};
 var b={b1:1,b2:2,b3:[4,5,6]}
 a.b=b;
 b.a=a;
 a.a4=[a,b];
 b.b4=[a,b];
 a.fn=function(){console.log(this.b);};
 
 var newa=shallowclone(a);

测试代码定义了一个自我引用的对象

a===a.a4[0];    // true
a===a.b.a;    // true

执行 shallowclone 方法获得了一个对象a的副本 newa

a === newa;              // false
newa ===  newa.a4[0];    // false
newa ===   newa.b.a;     // false
a === newa.a4[0];        // true
a === newa.b.a;          // true

测试执行速度:

/**
获取传入方法在规定时间内执行次数

示例:
var test = function(){

};
runtime(test,1)
表示test方法 在1秒中执行了6819005次
**/

/**
 * 获取传入方法在规定时间内执行次数
 * @param {any} fn 执行的方法
 * @param {any} time 规定的时间,单位为秒
 */
function runtime(fn, time) {
    var starttime = date.now();
    var count = 0;
    while (date.now() - starttime < time * 1000) {
        fn.call();
        count++;
    }
    return count;
}

深度克隆

代码:

/**
 * 深克隆
 * 
 * 示例:
 * var a={a1:1,a2:2,a3:[1,2,3]};
 * var b={b1:1,b2:2,b3:[4,5,6]}
 * a.b=b;
 * b.a=a;
 * a.a4=[a,b];
 * b.b4=[a,b];
 * a.fn=function(){console.log(this.b);return this.b;};
 * 
 * var newa=deepclone(a);
 * newa.a1=123;
 * newa.fn();
 */
function deepclone(source) {
    this.objkeycache = [];      // 对象缓存
    this.objvaluecache = [];    // 对象克隆缓存

    this.clone = function (source) {
        var target = createectype.call(this, source);
        for (var property in source) {
            if (source.hasownproperty(property)) {
                var value = source[property];
                if (typeof value === "number"
                    || typeof value === "boolean"
                    || typeof value === "symbol"
                    || typeof value === "string"
                    || typeof value === "function"
                    || typeof value === "undefined"
                    || value === null)
                    target[property] = value;
                else if (typeof value === "object") {
                    // 如果源对象在对象缓存中存在,就用对象克隆缓存中的值赋值
                    var index = this.objkeycache.indexof(value);
                    if (index >= 0)
                        target[property] = this.objvaluecache[index];   
                    else {
                        target[property] = this.clone( value);
                    }
                }
                else
                    throw "未知数据类型" + (typeof value);
            }
        }

        return target;
    };
    /**
     * 创建副本
     * @param {any} source
     */
    function createectype(source) {
        var target = {};
        if (array.isarray(source))
            target = [];
        this.objkeycache.push(source);
        this.objvaluecache.push(target);
        return target;
    }
    var newobject = this.clone(source);
    // 释放缓存,防止内存溢出
    this.objkeycache = [];
    this.objvaluecache = [];
    return newobject;
}

执行测试:

var a={a1:1,a2:2,a3:[1,2,3]};
var b={b1:1,b2:2,b3:[4,5,6]}
a.b=b;
b.a=a;
a.a4=[a,b];
b.b4=[a,b];
a.fn=function(){console.log(this.b);return this.b;};

var newa=deepclone(a);
a === newa;            // false
newa === newa.a4[0]    // true
newa === newa.b.a;     // true
a === newa.a4[0];      // false
a === newa.b.a;        // false

测试执行速度:

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网