【web前端面试必问7】浅拷贝和深拷贝

目录

一、先上面试的答案:

二、浅拷贝

三、深拷贝


一、先上面试的答案:

浅拷贝只拷贝源数据的第一层,修改拷贝的数据第一层,源数据也不会发生改变。修改拷贝的数据第二层源数据会发生改变。源数据的修改,拷贝的数据就会

深拷贝

二、浅拷贝

  • 浅拷贝的实现方式1

直接上案例分析

function simpleClone(initalObj) {
    var obj = {};  //定义对象 obj 为空对象
    for ( var i in initalObj) {  //循环initalObj 里的每个键值对 赋值 给对象的obj对象
        obj[i] = initalObj[i];
    }
    return obj;  // 返回赋值好的 obj 这个对象
}
 
var obj = {
    a: "hello",
    b:{
        a: "world",
        b: 21
    },
    c:["Bob", "Tom", "Jenny"],
    d:function() {
        alert("hello world");
    }
};
var cloneObj = simpleClone(obj);
 
console.log(cloneObj.a);
console.log(cloneObj.b);
console.log(cloneObj.c);
console.log(cloneObj.d);
 
//更改拷贝对象中的a,b,c,d,看看源对象是否变化
cloneObj.a = "changed";
cloneObj.b.a = "changed";
cloneObj.b.b = 25;
cloneObj.c = [1, 2, 3];
cloneObj.d = function() { alert("changed"); };
console.log(obj.a);    //hello
console.log(obj.b);    //{a:"changed",b:25},事实上就是只有对象是拷贝的引用类型
console.log(obj.c);    //['Bob','Tom','Jenny']
console.log(obj.d);    //...alert("hello world")

对上述代码分析: 

 

总结: 

浅拷贝就是拷贝了一层,除了对象是拷贝的引用类型,其他都是直接将值传递,有自己的内存空间的。更改第一层数据是无法修改源对象的。

  • 浅拷贝的实现方式2:Object.assign方法

Object.assign是ES6的新函数。Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。但是 Object.assign() 进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。

var obj1 = {
    a: "hello",
    b: {
        a: "hello",
        b: 21}
};
 
var cloneObj1= Object.assign({}, obj1);
cloneObj1.a = "changed";
cloneObj1.b.a = "changed";
console.log(obj1.a);  //hello
console.log(obj1.b.a); // "changed"

、深拷贝

复制的对象的第一层数据还是第二层数据的修改,不改变源数据。 

/* 深拷贝 */

      // 1.Array 数组深拷贝

      // 1.1 通过slice方法
      // slice()操作数组时,不会对原数组有影响,会产出一个新的数组。
      let arr1 = [1, 42, 5, 6]
      let arr2 = arr1.slice()
      arr2[0] = 100
      console.log(arr1) // [1, 42, 5, 6]
      console.log(arr2) // [100, 42, 5, 6]

      // 1.2 通过concat方法
      let arr3 = ['cat', 'dog', 'pig']
      let arr4 = [].concat(arr3)
      arr3[2] = 'big pig'
      console.log(arr3) // ['cat', 'dog', 'big pig']
      console.log(arr4) // ['cat', 'dog', 'pig']

      // 1.3 通过ES6语法中 …扩展运算符
      const fruits = ['1', '2', '3', '4', '5']
      const citrus = [...fruits]
      fruits[0] = 888
      console.log(fruits) //[888, '2', '3', '4', '5']
      console.log(citrus) //['1', '2', '3', '4', '5']

      // 1.4 通过 Array.from()
      const arr5 = ['1', '2', '3', '4', '5']
      const A = Array.from(arr5)
      arr5[0] = 888
      console.log(arr5) //[888, '2', '3', '4', '5']
      console.log(A) //['1', '2', '3', '4', '5']

      // 2 Object 对象的深拷贝
      // 2.1 通过Object.assign()方法
      let person = {
        name: 'xia',
        age: 25,
        height: 160,
      }
      let otherPerson = Object.assign({}, person) //person对象合并{}空对象
      person.age = 30
      console.log(person) //{name: 'xia', age: 30, height: 160}
      console.log(otherPerson) //{name: 'xia', age: 25, height: 160}

      // 3 万能转换器(对Array和Object等都适用)
      // 前面讲解了 Array和Object的深拷贝方法,但是对于有更深层次的结构关系(数组套数组 数组套对象 对象套对象等),上面的方法就失灵了,可以看下面的例子。
      let personArr = [{ name: 'xia' }, { name: 'zhang' }]
      let otherPersonArr2 = [...personArr]
      personArr[0].name = 'xia xia'
      console.log(personArr) //[{ name: 'xia xia' }, { name: 'zhang' }]
      console.log(otherPersonArr2) //[{ name: 'xia xia' }, { name: 'zhang' }]
      // 这个例子我们可以看出修改了源数据,那么拷贝的新数组也改变了。这种情况下给大家介绍一个万能转换器 JSON.parse(JSON.stringify(obj))深拷贝已有对象,它可以深拷贝多层级的,不用担心嵌套问题。
      let jack = {
        name: 'jack',
      }
      console.log(jack) //{name: 'jack'} 这是对象
      console.log(JSON.stringify(jack)) //{"name":"jack"} 这个是json字符串

      // JSON.parse()将json字符串解析成对象
      let obj = { name: '静茹秋叶' }
      console.log('obj: ', obj) //obj:  {name: '静茹秋叶'}
      console.log('json string: ', JSON.stringify(obj)) //json string:  {"name":"静茹秋叶"}

      let str = JSON.stringify(obj)
      console.log(str) //{"name":"静茹秋叶"}
      console.log('str to obj: ', JSON.parse(str)) //str to obj:  {name: '静茹秋叶'}

      let x = JSON.parse(JSON.stringify(obj))
      x.name = '庄领'
      console.log(obj) //{name: '静茹秋叶'}
      console.log(x) //{name: '庄领'}

猜你喜欢

转载自blog.csdn.net/m0_56349322/article/details/124058385