二. JavaScript 数组 和 对象 的深浅拷贝

前提:原始数据类型和对象类型赋值时的差异

  JavaScript的数据类型分为:原始数据类型和对象类型。二者在内存中存放的方式不同,导致了其赋值时差异。分别举个栗子 

1.原始数据类型:Undefined、Null、Boolean、Number以及String。

2.对象类型

  var x = 1;
  var y = x;  //y获得了和x同样的值
  y = 2;
  console.log(x);  // 1

  var m = [1,2]; //m存放的是指向[1,2]这个数组对象的引用地址
  var n = m; //n也获得 [1,2]数组对象的引用地址
  n[0] = 3;
  console.log(m);  //[3,2] 

浅拷贝?

  顾名思义,浅拷贝就是流于表面的拷贝方式;当属性值为对象类型时,只拷贝了对象数据的引用,导致新旧数据没有完全分离,还会互相影响。再举个栗子···

var array1 = ['a',1,true,{name:'lei',age:18}];
var array2 = array1.concat();   //注意不能直接=,不然直接数组对象,没有原始类型了
array2[0] = 'b';               //array1[0]是原始数据类型 所以是直接赋值的
array2[3].name = 'zhang';      //array1[3]是对象数据类型 所以拷贝的是对象的引用,其实还是和原数组使用同一对象
console.log(array1);         //  ['a',1,true,{name:'zhang',age:18}]

如何实现浅拷贝

  1. 上栗中的  array.concat()或者array.slice() 是特殊的实现数组浅拷贝的方式。
  2. 如何自己实现呢?遍历对象/数组的每个属性,然后赋值给一个新的对象不就行了么,如下实现
//实现浅拷贝
  function shallowCopy( target ){
    if(typeof target !== 'object') return ;
    //判断目标类型,来创建返回值
    var newObj = target instanceof Array ? [] : {};
    for(var item in target){
      //只复制元素自身的属性,不复制原型链上的
      if(target.hasOwnProperty(item)){
        newObj[item] = target[item]
      }
    }
    return newObj
  }

  var test = [1,'a',{name:'lei',age:18}];
  var copy = shallowCopy(test);
  console.log(copy[2].name);   //lei

  copy[0] = 0;
  copy[2].name = 'zhang';
  console.log(test[0]);        //1       原数据不变
  console.log(test[2].name);   //zhang   原数据也被修改

深拷贝及其实现

  从浅拷贝解释基本可以明白,深拷贝就是 ‘完全’拷贝,拷贝之后新旧数据完全分离,不再共用对象类型的属性值,不会互相影响。

//实现深拷贝
function deepCopy( target ){
  if(typeof target !== 'object') return ;
  //判断目标类型,来创建返回值
  var newObj = target instanceof Array ? [] : {};

  for(var item in target){
    //只复制元素自身的属性,不复制原型链上的
    if(target.hasOwnProperty(item)){
      newObj[item] = typeof target[item] == 'object' ? deepCopy(target[item]) : target[item]  //判断属性值类型
    }
  }
  return newObj
}

//测试
var test = [1,'a',{name:'lei',age:18}];

var copy2 = deepCopy(test);
copy[0] = 0;
copy2[2].name = 'zhang'
console.log(test);         //[1,'a',{name:'lei',age:18}]  未受到影响
原文地址:https://www.cnblogs.com/hy-space/p/8945595.html