0


JavaScript面试精讲(七)——谈谈深拷贝和浅拷贝

一.浅拷贝

浅拷贝
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主”对象进行拷贝,但不会复制主对象里面的对象。”里面的对象“会在原来的对象和它的副本之间共享。

1.JavaScript中变量包含两种不同的数据类型基本数据类型 引用数据类型

  • 基本类型值指的是简单的数据段,包括es6里面新增的一共是有6种,具体如下:number、string、boolean、null、undefined、symbol。
  • 引用类型值指那些可能由多个值构成的对象,只有一种如下:object。 在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型值。

2.基本类型与引用类型最大的区别实际就是 传值与传址 的区别

值传递:基本类型采用的是值传递。
地址传递:引用类型则是地址传递,将存放在栈内存中的地址赋值给接收的变量。

接下来看几个例子就会理解两者区别

数组

var arra=[1,2,3,4,5]
var arra1=arra
arra1.push(9)
console.log(arra);
console.log(arra1);

向操作一个数组另一个数组也受到影响,因为他们指向同一地址,如图所示

对象之间的赋值 基本数据类型之间的赋值同理都会导致这样的问题

二.深拷贝

深拷贝不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上,所以对一个对象的修改并不会影响另一个对象。

数组的深拷贝

方法一:for循环

  let arr1 = [1,2,3];
  let arr2 = copyArr(arr1);
  function copyArr(arr){
      let res=[];
      for(let i=0,length=arr.length;i<length;i++){
          res.push(arr[i]);
      }
      return res;
  }

方法二 slice()方法

利用数组自身的方法,slice、

 let arr1 = [1,2,3];
 let arr2 = arr1.slice(0);

方法三 concat()方法

 let arr1 = [1,2,3];
 let arr2 = arr1.concat();

方法四 扩展运算符

 let arr1 = [1,2,3];
 let [...arr2] = arr1;

方法五 Array.from

如果参数是一个真正的数组,Array.from会返回一个一模一样的新数组

 let arr1 = [1,2,3];
 let arr2 = Array.from(arr1);

对象的深拷贝

方法一 for循环

   let obj1={count:1,name:'grace',age:1};
    let obj2 = copyObj(obj){
        let res = {};
        for(let key in obj){
              res[key]=obj[key];
           }
        return res;
    }

方法二 Json

万能转换器 JSON.parse(JSON.stringify(obj))深拷贝已有对象,它可以深拷贝多层级的,不用担心嵌套问题。

  • JSON.stringfy() 将对象序列化成json对象
  • JSON.parse() 反序列化——将json对象反序列化成js对象
 let obj = {
     name: '静茹秋叶'
 }
 console.log('obj: ', obj)
 console.log('json string: ', JSON.stringify(obj))

 let str = JSON.stringify(obj)
 console.log('--------------')
 console.log(str)
 console.log('str to obj: ', JSON.parse(str))

方法三 扩展运算符

let obj1={count:1,name:'grace',age:1};
let {...obj2} = obj1;

方法四 Object.assign()方法 ES6新增加

ES6的Object.assign() Object.assign(target, …sources)用于对象的合并,将源对象中的所有可枚举属性,复制到目标对象中,并返回合并后的目标对象。后来的源对象的属性值,将会覆盖它

 let person = {
     name: 'xia',
     age: 25,
     height: 160
 }
 let otherPerson = Object.assign({}, person)
 person.age = 30

 console.log(person)
 console.log(otherPerson)

之前的对象的属性。

标签: javascript

本文转载自: https://blog.csdn.net/qq_56989560/article/details/124635258
版权归原作者 Mr.指尖舞者 所有, 如有侵权,请联系我们删除。

“JavaScript面试精讲(七)&mdash;&mdash;谈谈深拷贝和浅拷贝”的评论:

还没有评论