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

对象以及数组的深浅拷贝(新值与旧值在改变任意值的情况下不相互干扰就是深拷贝) #2

Open
QinZonger opened this issue Dec 26, 2018 · 0 comments
Labels

Comments

@QinZonger
Copy link
Owner

我们在对数据进行备份的时候,如果这个数据是基本的数据类型,那么很好办,通过赋值实现复制即可。如果在使用JavaScript对数组或对象进行操作的时候,我们经常需要将数组或对象进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。这个问题就是深拷贝和浅拷贝的问题。

数组

浅拷贝

            let arr = ['old', 1, true, null, undefined];
            let new_arr = arr.concat();

            new_arr[0] = 'new';

            console.log(arr) // ["old", 1, true, null, undefined]
            console.log(new_arr) // ["new", 1, true, null, undefined]

但是如果数组嵌套了对象或者数组的话,我们会发现,无论是新数组还是旧数组都发生了变化,也就是说使用 concat 方法,克隆的并不彻底。
如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。
我们把这种复制引用的拷贝方法称之为浅拷贝,与之对应的就是深拷贝,深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

let obj1 = [{a: '1',b: '2'}]
            var arr = [];
            arr = arr.concat(obj1);
            arr[0].a = "test";
            console.log(arr); //[{a: "test", b: "2"}]
            console.log(obj1);//[{a: "test", b: "2"}]

深拷贝

    var arr = ['old', 1, true, ['old1', 'old2'], {old: 1}]
    var new_arr = JSON.parse(JSON.stringify(arr));
    arr[4].old="test";
    console.log(new_arr);// ['old', 1, true, ['old1', 'old2'], {old: "test"}]
    console.log(arr);// ['old', 1, true, ['old1', 'old2'], {old: 1}]

对象

浅拷贝
浅拷贝是对象共用一个内存地址,对象的变化相互影响。比如常见的赋值引用就是浅拷贝:

    let srcObj = {'name': 'lilei', 'age': '20'};
    let copyObj = srcObj;
    copyObj.age = '22';
    console.log(srcObj) //22
    console.log(copyObj)//22

深拷贝
法 一 :解构赋值

    let obj = {
      one: 1,
      two: 2,
    }
     
    let newObj = { ...obj };
    obj.one=9
    console.log(obj)//9
    console.log(newObj)//1

法 二 :JSON.parse(JSON.stringify(obj))

    let srcObj = {'name': '明', grade: {'chi': '50', 'eng': '50'} };
    let copyObj2 = JSON.parse(JSON.stringify(srcObj));
    copyObj2.grade.chi=90
    console.log(srcObj) //50
    console.log(copyObj2) //90
@QinZonger QinZonger added the ES6 label Dec 26, 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