浅拷贝与深拷贝(二)代码实现浅拷贝

本文深入探讨了浅拷贝的概念及其在JavaScript中的多种实现方式,包括循环遍历、Object.assign、Array.prototype.concat、Array.prototype.slice以及展开运算符等。通过实例展示了每种方法的特点和局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

代码实现浅拷贝

1. 循环遍历对象可枚举值
// 手写浅拷贝
const arr1 = [1, 2, ['html', 'css'], 4];

const shallowClone = (arr) => {
  const dst = [];
  for (let prop in arr) {
    console.log(prop)
    if (arr.hasOwnProperty(prop)) {
        dst[prop] = arr[prop];
    }
  }
  return dst;
}

const arr2 = shallowClone(arr1);
arr2[2].push('Javascript');
arr2[3] = 5;

console.log(arr1);
// [ 1,2,['html','css','Javascript'], 4 ]
console.log(arr2);
// [1,2,['html','css','Javascript'], 5 ]

手写思路:

  • for... in : 遍历Object对象arr1,将骑可枚举值列举出来。
  • hasOwnProperty () : 检查该枚举值是否属于该对象arr1, 如果是继承过来的就去掉,如果是自身的则进行拷贝。
2. Object.assign()

const obj = {
    name : "张三",
    age : "16",
    skill : {
        read : "html",
        write : "css"

    },
    like : ['吃饭','睡觉','敲代码']
}

const newobj = Object.assign({},obj)

newobj.name = "李四"
newobj.skill.read = "js"
newobj.like = ["玩耍"]

console.log(obj)  
// { name: '张三',
//   age: '16',
//   skill: { read: 'js', write: 'css' },
//   like: [ '吃饭', '睡觉', '敲代码' ] }
console.log(newobj)
// { name: '李四',
//   age: '16',
//   skill: { read: 'js', write: 'css' },
//   like: [ '玩耍' ] }

Object.assign() 方法是ES6新增方法,可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

通过代码可以看到的是,Object.assign() 对于第一层的数据来说,是深拷贝,对于第二层及以上的数据来说,是浅拷贝。

3. Array. prototype. concat ()

concat ()是数组的一个内置方法,用户合并两个或者多个数组。这个方法不会改变现有数组,而是返回一个新数组。


const arr = [1,2,{ name : "张三", age : "16"}]

const newarr = arr.concat()

newarr[0] = 3
newarr[2].name = "李四"

console.log(arr)  // [ 1, 2, { name: '李四', age: '16' } ]
console.log(newarr) // [ 3, 2, { name: '李四', age: '16' } ]

4. Array. prototype. slice ()

slice()也是数组的一个内置方法,该方法会返回一个新的对象。slice()不会改变原数组。


const arr = [1,2,{ name : "张三", age : "16"}]


const newarr = arr.slice()

newarr[0] = 3
newarr[2].name = "李四"
 
console.log(arr)  // [ 1, 2, { name: '李四', age: '16' } ]
console.log(newarr) // [ 3, 2, { name: '李四', age: '16' } ]

5.展开运算符… obj

展开运算符是ES6中新提出来的一种运算符。在拷贝数组、对象以及拼接数组等方面都可以使用。这边我们也可以尝试下使用const obj2 = {..obj1} 的形式进行浅拷贝。

// 对数组

const arr = [1,2,{ name : "张三", age : "16"}]
const newarr = [...arr]

console.log(arr) // [ 1, 2, { name: '张三', age: '16' } ]
console.log(newarr) // [ 1, 2, { name: '张三', age: '16' } ]

newarr[0] = 3
newarr[2].name = "李四"

console.log(arr) // [ 1, 2, { name: '李四', age: '16' } ]

console.log(newarr) // [ 3, 2, { name: '李四', age: '16' } ]

// 对于对象进行浅拷贝
const obj = {
    name : "张三",
    age : "16",
    like : ['吃饭','睡觉','敲代码']
}
const newobj = {...obj}

newobj.like.push('打豆豆')
newobj.name = "李四"

console.log(obj) 
// { name: '张三', age: '16', like: [ '吃饭', '睡觉', '敲代码', '打豆豆' ] }
console.log(newobj) 
// { name: '李四', age: '16', like: [ '吃饭', '睡觉', '敲代码', '打豆豆' ] }


完整文章见:

自建博客地址:ahuiyo的博客 - 教你手撸深拷贝与浅拷贝

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值