Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

js浅拷贝与深拷贝(2017.09.04) #18

Open
aermin opened this issue Feb 13, 2018 · 0 comments
Open

js浅拷贝与深拷贝(2017.09.04) #18

aermin opened this issue Feb 13, 2018 · 0 comments
Labels

Comments

@aermin
Copy link
Owner

aermin commented Feb 13, 2018

深浅拷贝区别

深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象(引用类型)的。

复制引用(引用类型)的拷贝方法称之为浅拷贝,也因为直接复制引用类型,导致新旧对象共用一块内存地址,会互相影响,具体看例子

深拷贝就是指完全的拷贝一个对象,将原对象的各个属性递归复制下来。这样即使嵌套了对象,两者也相互分离。

浅拷贝

var shallowCopy = function(obj) {
    if (typeof obj !== 'object') return;      // 只拷贝对象
    var newObj = obj instanceof Array ? [] : {};     // 根据obj的类型判断是新建一个数组还是对象
    for (var key in obj) {      // 遍历obj,并且判断是obj的属性才拷贝
        if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key];
        }
    }
    return newObj;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1])  // 5
shallowObj.a = 5;
console.log(obj.a) // 1 

备注:

①hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性。Object.prototype.hasOwnProperty(),;
②instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。换种说法就是如果左侧的对象是右侧类的实例, 则表达式返回true, 否则返回false 。

原理

遍历对象,然后把属性和属性值都放在一个新的对象

具体:判断是参数否为对象,是数组还是object;用 for in 遍历所传的参数对象,并用 if (arg.hasOwnProperty(prop)) 忽略掉继承属性,然后赋值给临时创建的对象,最后返回此对象。

深拷贝

实现一个深拷贝在拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用深拷贝函数就OK了

var deepCopy = function(obj) {
    if (typeof obj !== 'object') return;
    var newObj = obj instanceof Array ? [] : {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
        }
    }
    return newObj;
}

var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
shallowObj.arr[1] = 5;
console.log(obj.arr[1])  // 3
shallowObj.a = 5;
console.log(obj.a) // 1 

性能问题

尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

本文参考地址

待续:

https://www.zhihu.com/question/23031215
https://yanhaijing.com/javascript/2018/10/10/clone-deep/
https://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript
https://segmentfault.com/a/1190000002789651

@aermin aermin added the js label Feb 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant