JavaScript拷贝

一、JavaScript ------ 基于原型的面向对象语言

        JavaScript 是一门面向对象的语言,JavaScript 中的所有事物都是对象:字符串、数值、数组、函数等等,此外,JavaScript 允许自定义对象。下面我们先看一个例子:

var a = {n: 1}  
var b = a;  
a.x = a = {n: 2};  
console.log(a.x);    // undefined
console.log(b.x);    // {n:1, x: object}

        上面的例子中,a中添加了属性x,这时在b中也增加了属性x的引用,这让人不由想到了java中的浅拷贝概念。同样是面向对象的语言,因此javascript中同样存在着深拷贝与浅拷贝的概念;不同的是java是基于类的面向对象语言,对象(object)依靠 类(class)来产生,而javascript是基于原型的面向对象语言,对象(object)则是依靠构造器(constructor)利用原型(prototype)构造出来的。

二、浅拷贝与深拷贝的区别

        JS 中的浅拷贝与深拷贝,只是针对复杂数据类型(Object,Array)的复制问题。

        浅拷贝与深拷贝都可以实现在已有对象上再生出一份的作用,但是对象的实例是存储在堆内存中,然后通过一个引用值去操作对象,由此拷贝的时候就存在两种情况了:拷贝引用和拷贝实例,这也是浅拷贝和深拷贝的区别。上文中出现的例子是最简单的浅拷贝,下面我们再看一个例子:

var a = [{c:1}, {d:2}, 3];
var b = a.slice();
a[0].c = 3;
console.log(b[0].c); // 输出 3,说明其元素拷贝的是引用
a[2] = 5;
console.log(b[2]); // 输出 undefined,说明外层数组拷贝的是实例

        在这种情况下,变量b拷贝的是以a为原型的实例,如果其属性元素为复杂数据类型时,内层元素拷贝引用,如果其属性为简单数据类型时,内层元素拷贝的是实例。

三、深拷贝的写法

function deepClone( obj ) { 
    var copy; 
    switch( typeof obj ) { 
        case "undefined": 
            break; 
        case "number": 
            copy = obj - 0; 
            break; 
        case "string": 
            copy = obj + ""; 
            break; 
        case "boolean": 
            copy = obj; 
            break; 
        case "object": 
            //object 分为两种情况 对象(Object)和数组(Array) 
            if(obj === null) { 
                copy = null; 
            } else { 
                if( Object.prototype.toString.call(obj).slice(8, -1) === "Array") { 
                    copy = []; 
                    for( var i = 0 ; i < obj.length ; i++ ) { 
                        copy.push(clone(obj[i])); 
                    }
                } else { 
                    copy = {}; 
                    for( var j in obj) { 
                        copy[j] = clone(obj[j]); 
                    }
                }
            }
            break; 
        default: 
            copy = obj;  
    }
    return copy;
}

        此外,深拷贝还可以使用以下方法:

  1. JSON.stringify() 和 JSON.parse() 的搭配使用
  2. jQuery的 $.extend(true,{},obj)
  3. lodash的_.cloneDeep和_.clone(value, true)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值