实践总结 js 深拷贝 浅拷贝

总结

实践出真知。

浅拷贝,深拷贝的区别,首先要看拷贝是怎么实现的,再谈区别。

var a, b=a;

基本类型使用赋值操作,仅赋值,修改不会相互影响。

引用类型赋值引用地址为同一个,修改会相互影响。

以下实现方式的区别:

浅拷贝,修改一个对象中的数组元素,另一个对象也会被修改。如果是修改属性或增加属性,则不影响。

深拷贝,无论修改什么,都不影响另一个对象。

实际开发中都是用的深拷贝,没用过浅拷贝。

另,工厂函数,可以看做是已知固定属性的深拷贝。vue中,当 props 属性值为对象或数组时,使用的就是返回工厂函数的方式。

const compB = {
  template: `<div>
              <p>age:{
   
   {age}}</p>
              <p>sex:{
   
   {sex}}</p>
              <p>hobby.ball:{
   
   {hobby.ball}}</p>
              <p>hobby.game:{
   
   {hobby.game}}</p>
            </div>`,
  props: {
    age: Number,
    sex: {
      type: String,
      default: 'male',
      validator(value) {
        return value === 'male' || value === 'female'
      }
    },
    hobby: {
      type: Object,
      default() {
        return {
          ball: '',
          game: ''
        }
      }
    }
  }
}

浅拷贝

测试预览

undo:js执行顺序bug,后修改的也会影响先前打印的结果。

测试代码

<script>
//浅拷贝实例:此递归方法不包含数组对象
function shallowCopy(src) {
  var newobj = {};
  for (var prop in src) {
    if (src.hasOwnProperty(prop)) {
      //仅拷贝私有属性,如toString这些对象公共属性不拷贝
      newobj[prop] = src[prop];
    }
  }
  return newobj;
}

var obj = {
  strA:"test_A",
  arr: [11,22,33],
  obj:{a:{b:1},c:2},
  fun:function(a,b){return a-b}
};
console.log("打印 obj"); 
console.log(obj); 

var shallowObj = shallowCopy(obj);
console.log("shallowObj浅拷贝 obj,打印 shallowObj"); 
console.log(shallowObj); 

shallowObj.arr[0] = 1;
shallowObj.strA="testEdit_A"
shallowObj.strB="testAdd_B"
console.log("修改 shallowObj,打印 shallowObj"); 
console.log(shallowObj);
console.log("打印 obj"); 
console.log(obj);
</script>

深拷贝

测试预览

测试代码

<script>
//深拷贝,要想达到深拷贝就需要用递归
function deepClone(obj){
  var newObj = obj instanceof Array ? []:{};
  if(typeof obj !== 'object'){
    return obj;
  }else{
    for(var i in obj){
      newObj[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i];
    }
  }
  return newObj;
}

var obj = {
  strA:"test_A",
  arr: [11,22,33],
  obj:{a:{b:1},c:2},
  fun:function(a,b){return a-b}
};
console.log("打印 obj"); 
console.log(obj); 

//测试对象深拷贝
var deepCloneObj = deepClone(obj);
console.log("deepCloneObj 深拷贝 obj,打印 deepCloneObj");
console.log(deepCloneObj);
console.log("修改 deepCloneObj ,打印 deepCloneObj");
deepCloneObj.arr[0] = 1;
deepCloneObj.strA="testEdit_A"
deepCloneObj.strC="testAdd_C"
console.log(deepCloneObj);
console.log("打印 obj");
console.log(obj);

//测试数组深拷贝
var testArr = [11, 22, 33, 44, "aa", "55", [1, 2,3,4]];
console.log("打印 testArr 数组");
console.log(testArr);

var arr = deepClone(testArr);
console.log("arr 拷贝了 testArr,打印 arr");
console.log(arr);

testArr[0] = 1;
console.log("修改 testArr,打印 testArr");
console.log(testArr);
console.log("打印 arr");
console.log(arr);
</script>

推荐关联阅读 

详解JavaScript栈内存与堆内存

讲的比较清楚

https://www.jb51.net/article/159120.htm

猜你喜欢

转载自blog.csdn.net/Irene1991/article/details/114402477