js深浅拷贝

文章介绍了JavaScript中实现对象和数组浅拷贝与深拷贝的多种方法,包括使用Object.assign(),ES6的解构赋值,Object.create(),for循环,slice(),concat(),JSON.parse和JSON.stringify等,并讨论了它们的局限性和适用场景。
摘要由CSDN通过智能技术生成

浅拷贝

代码如下:

 var array=[1,2,3]
 var array_1=[1,2,3]
 array_1.push(4)
 console.log(array)     //(3) [1,2,3]
 console.log(array_1)   //(4) [1,2,3,4]

Object.assign() 对象合并

 var obj = {
    a:'111',
    b:'2222',
    c:{
      aa:11,
      bb:222,
      cc:222
    },
  }
  var obj2 = Object.assign(obj)
  obj.a = 999999
  console.log(obj2) //  同obj
  console.log( obj.a) // 999999

ES6 对象解构

var obj = {
    a:'111',
    b:'2222',
    c:{
      aa:11,
      bb:222,
      cc:222
    },
  }
  var obj2 = {...obj}
  obj.a = 999999
  obj.c.aa = 999999
  console.log(obj2) // 同obj
  console.log( obj.a) // 999999
  console.log( obj2.a) // 111
  console.log( obj.c.aa) //999999
  console.log( obj2.c.aa) //999999

Object.create() 创建对象

var obj = {
    a:'111',
    b:'2222',
    c:{
      aa:11,
      bb:222,
      cc:222
    },
  }
  var obj2 = Object.create(obj)
  obj.a = 333
  console.log(obj2) // 同obj
  console.log( obj.a) // 333
  console.log( obj2.a) // 333

深拷贝

1、for循环

代码如下:

 var array_2=[1,2,3]
 var array_3=[]
 for(var i=0;i<array_2.length;i++){
     array_3.push(array_2[i])
 }
 array_3.unshift(0)
 console.log(array_2)    //(3) [1,2,3]
 console.log(array_3)    //(4) [0,1,2,3]

2、slice()

代码如下:

 var array_4 = [1, 2, 3]
 var array_5 = array_4.slice(0)
 array_5.push(4)
 console.log(array_4)   //(3) [1,2,3]
 console.log(array_5)   //(4) [1,2,3,4]

3、concat()

代码如下:

 var array_6 = [1, 2, 3]
 var array_7 = array_6.concat()
 array_7.shift()
 console.log(array_6)   //(3) [1,2,3]
 console.log(array_7)   //(2) [2,3]

对象

代码如下:

    var obj_1 = {
        name: 'name',
        age: 18
    }
    var obj_2 = {}
    for (x in obj_1) {
        obj_2[x] = obj_1[x]
    }
    obj_2.name = 'name1'
    console.log(obj_1)    //{name:'name',age:18}
    console.log(obj_2)    //{name:'name1',age:18)

利用JSON.parse 和JSON.stringfy

代码如下:

  var obj1={
  name:'li',
  hobit:['摄影','羽毛球']
  }
  var obj2=JSON.parse(JSON.stringify(obj1))
  obj2.hobit,push('游泳')
  console.log(obj1)   //{name:'li',hobit:['摄影','羽毛球']}
  console.log(obj2)   //{name:'li',hobit:['摄影','羽毛球','游泳']}

1、使用JSON.parse 和JSON.stringfy也会有很多限制:
如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象;
3、如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
6、如果对象中存在循环引用的情况也无法正确实现深拷贝;

循环递归调用(适用于对象和数组)

function deepCopy(target) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        for (const key in target) {
         if (target.hasOwnProperty(key)) {
            cloneTarget[key] = deepCopy(target[key]);
          }
        }
        return cloneTarget;
    } else {
        return target;
    }
};
const a = [{name:'张三'},1];
const b = deepCopy(a);
a[0].name='李四';
a[1]=2; 
const c= {age:1};
const d = deepCopy(c); 
c.age = 2;
console.log(a); // [{name:'李四'}, 2]
console.log(b); // [{name:'张三'}, 1]
console.log(c); // {age: 2}
console.log(d); // {age: 1}

ES6扩展运算符

const a = [{ name: "张三" }];
const b = [...a]; 
a[0].name = '李四';
console.log(a); // [{ name: "李四" }]
console.log(b); // [{ name: "李四" }]

Object.assign

let arr1 = [1, 2, 3, 4];
let newObj = Object.assign([], arr1);
newObj[0] = 6;
console.log(newObj[0]);
console.log(arr1);
console.log(newObj);
console.log("---------------------------------------------------")
// 多层数据
let arr2 = [[1,2], [2,4], [3,6], [4,9]];
let newObj2 = Object.assign([], arr2);
newObj2[2][0] = 6;
console.log(newObj2[2][0]);
console.log(arr2);
console.log(newObj2);

在这里插入图片描述

Array.map

// 单层数据
let arr1 = [1, 2, 3, 4];
let newObj = arr1.map(function(value){
  return value;
});
newObj[2] = -1;
console.log(newObj[2]);
console.log(arr1);
console.log(newObj);
console.log("---------------------------------------------------")
// 多层数据
let arr2 = [[1,2], [2,4], [3,6], [4,9]];
let newObj2 = arr2.map(function(value){
  return value;
});
newObj2[2][0] = -1;
console.log(newObj2[2][0]);
console.log(arr2);
console.log(newObj2);

在这里插入图片描述

json暴力转化

var obj = {name:'123'}
var obj2 = JSON.parse(JSON.stringify(obj)

JSON拷贝与局限性,当值为undefined、function、symbol时候,在转化过程中会被忽略

缓存克隆

function deepClone(target,map = new Map()) {
  if (typeof target === 'object' && target) {
    const cache = map.get(target)
    if (cache) {
      return cache
    }
    const result = Object.prototype.toString.call(obj) === '[object Object]' ? {} : []
    map.set(target, result)
    Object.keys(target).forEach(key => {
      result[key] = deepClone(target[key],map)
    })
    return result;
  }
  return target;
}

递归

function deepClone(target) {
  // 如果是对象,且不是原始值null
  if (typeof target === 'object' && target) {
    // 创建容器
    const result = Object.prototype.toString.call(obj) === '[object Object]' ? {} : []
    Object.keys(target).forEach(key => {
      result[key] = deepClone(target[key])
    })
    return result;
  }
  return target;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值