js深度克隆

js深度克隆
js对象组成
说对象的深度克隆之前,要先明白JS 中对象的组成。 
以一句话说js中一切皆对象

具体数据类型分为两种: 
- 原始数据类型 
- 引用数据类型

原始数据类型:其中存储的是对象的实际地址。eg. 
number、string、boolean、还有两个特殊的null、undefined

引用数据类型:其中存储的是对象的引用地址。eg. 
array、function、object

克隆的概念
浅度克隆:原始类型为值传递,对象类型仍为引用传递。

深度克隆:所有元素或属性均完全复制,与原对象完全脱离,也就是说所有对于新对象的修改都不会反映到原对象中。

顾名思义,克隆就是将a同样复制一份变成b,那何为深度克隆呢?先来看一个例子:

浅克隆
       

  var a = 1;
        var b = a;
        a = 10;
        console.log(b); // 1

        var a = 'hello';
        var b = a;
        a = 'world';
        console.log(b); // hello

        var a = true;
        var b = a;
        a = false;
        console.log(b); // true


并且复制完成后原变量的值依旧可以重新赋值并且不影响拷贝文件

 

        var a = 1;
        var b = a;
        a = 10;
        console.log(b); console.log(a);// 1,10

        var a = 'hello';
        var b = a;
        a = 'world';
        console.log(b); console.log(a);// hello,world

        var a = true;
        var b = a;
        a = false;
        console.log(b); console.log(a);// true,false


对于原始数据类型来说,这种赋值式克隆已可以实现。 
对于function基本也可以利用简单赋值实现克隆:

function clone(obj) {
  var o = obj instanceof Array ? [] : {};
  for(var k in obj) 
    o[k] = typeof obj[k] === Object ? clone(obj[k]) : obj[k];
  return o;
}

var a = [[1, 2, 3], [4, 5, 6, 7]];
var b = clone(a);
console.log(b);


深度克隆
但是对于引用数据类型对象来说:

var a = [0, 1, 2, 3]; 
var b = a; 
a.push(4); 
console.log(b); // [0, 1, 2, 3, 4]

由于引用类型数据存储在应用地址内存中,因此赋值复制的也是这一块地址,因此相当于两个数组对象引用了一块数据地址,所以对a或者b的任何操作或者改变都会体现在对象中。

为了避免这种情况,引入了深度克隆。

    function clone(obj){
        var buf;
        if(obj instanceof Array){
            buf = [];
            var i = obj.length;
            while(i--){
                buf[i] = clone(obj[i]);
            }
            return buf;
        }
        else if(obj instanceof Object){
            buf = {};
            for(var k in obj){
                buf[k] = clone(obj[k]);
            }
            return buf;
        }
        else{
            return obj;
        }
    }

或者精简的写法:

function clone(obj) {
  var o = obj instanceof Array ? [] : {};
  for(var k in obj) 
    o[k] = typeof obj[k] === Object ? clone(obj[k]) : obj[k];
  return o;
}

var a = [[1, 2, 3], [4, 5, 6, 7]];
var b = clone(a);
console.log(b);


 

/**
 * 对一个object进行深度拷贝
 *
 * 使用递归来实现一个深度克隆,可以复制一个目标对象,返回一个完整拷贝
 * 被复制的对象类型会被限制为数字、字符串、布尔、日期、数组、Object对象。不会包含函数、正则对象等
 *
 * @param  {Object} source 需要进行拷贝的对象
 * @return {Object} 拷贝后的新对象
 */
function cloneObject (source) {
    var result = source, i, len;
    if (!source
        || source instanceof Number
        || source instanceof String
        || source instanceof Boolean) {
        return result;
    } else if (isArray(source)) {
        result = [];
        var resultLen = 0;
        for (i = 0, len = source.length; i < len; i++) {
            result[resultLen++] = cloneObject(source[i]);
        }
    } else if (isPlain(source)) {
        result = {};
        for (i in source) {
            if (source.hasOwnProperty(i)) {
                result[i] = cloneObject(source[i]);
            }
        }
    }
    return result;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值