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

深拷贝和浅拷贝 #22

Open
ZhangHanwen96 opened this issue Mar 9, 2021 · 0 comments
Open

深拷贝和浅拷贝 #22

ZhangHanwen96 opened this issue Mar 9, 2021 · 0 comments

Comments

@ZhangHanwen96
Copy link
Owner

ZhangHanwen96 commented Mar 9, 2021

shallow copy

1.Object.assign (可以处理一层的浅拷贝)

var obj = { a: {a: "hello", b: 21} };
var initalObj = Object.assign({}, obj);

initalObj.a.a = "changed";
console.log(obj.a.a); // "changed"

需要注意的是:
Object.assign()可以处理一层的深度拷贝,如下:

var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = Object.assign({}, obj1);
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }

2. "="赋值

Deep copy

1. JSON做字符串转换

var obj1 = { body: { a: 10 } };
var obj2 = JSON.parse(JSON.stringify(obj1));
obj2.body.a = 20;
console.log(obj1);
// { body: { a: 10 } } <-- 沒被改到
console.log(obj2);
// { body: { a: 20 } }
console.log(obj1 === obj2);
// false
console.log(obj1.body === obj2.body);
// false

问题

但是这种方法也有不少坏处,譬如它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。

这种方法能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。RegExp对象是无法通过这种方式深拷贝。

  • 只能序列化对象的可枚举的自有属性 例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;

2.递归拷贝

function deepClone(obj) {
    if (obj === null) return null; //null 的情况
    if (obj instanceof RegExp) return new RegExp(obj); //正则表达式的情况
    if (obj instanceof Date) return new Date(obj); //日期对象的情况
    if (typeof obj == 'Function') return new function(obj){}; //函数的情况

    if (typeof obj != "object") {
        //非复杂类型,直接返回 也是结束递归的条件
        return obj
    }

    //[].__proto__.constructor=Array()
    //{}.__proto__.constructor=Object()
    var newObj = new obj.__proto__.constructor;

    for(let key in obj) {
        if(Object.hasOwnProperty(key)) {
             newObj[key] = deepClone(obj[key])
        }
    }

    return newObj
}

3.Object.create()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant