前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在 JavaScript 中如何克隆对象?

在 JavaScript 中如何克隆对象?

作者头像
前端小智@大迁世界
发布2022-06-15 14:21:05
4.6K0
发布2022-06-15 14:21:05
举报
文章被收录于专栏:终身学习者终身学习者

作者:Luigi Nori 译者:前端小智 来源:stackabuse

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

当我们想要复制原始值和引用值(对象)时,它们的行为会大不相同。

原始值

我们假设一个变量 name 具有一个与之关联的原始值(number,string,boolean,undefined 和null)。 如果我们将此变量 name 复制到另一个变量name2 ,则原始变量的任何修改都不会影响到第二个变量,因为它们是原始值。

代码语言:javascript
复制
let name="前端小智";
let name2= name;
console.log (name, name2); // 前端小智, 前端小智
name="王大冶";
console.log (name,name2); // 王大冶 前端小智

引用值

但是,如果我们对引用类型的值进行相同的操作,则我们对一个变量所做的任何更改也将反映在另一个变量中,因为两个变量都指向同一对象。

数组

要拷贝数组,slice()方法用于创建数组的新副本。 可以独立修改此副本,而不会影响原始数组。

如果未传递任何参数,则它会精确复制数组,但数字也可以作为参数传递。 如果仅传递一个数字,它将确定我们要从其进行复制的索引的值,而如果传递两个数字,则将标记开始和结束。

代码语言:javascript
复制
// 示例1
const names = ['前端小智', '王大冶', '小力'];
const names2 = names;
console.log(names, names2);
// ["前端小智", "王大冶", "小力"] 
// ["前端小智", "王大冶", "小力"] 

// 示例2
names2[2] = '前端小力';
console.log(names, names2);
//  ["前端小智", "王大冶", "前端小力"] 
//  ["前端小智", "王大冶", "前端小力"] 

// 示例3
const name2 = names.slice();
names[2] = '我是隔壁老智';
console.log(name2, names2)
// ["前端小智", "王大冶", "前端小力"]
//  ["前端小智", "王大冶", "我是隔壁老智"]

对象

当引用值是一个对象时,也会发生同样的情况,对其属性之一的任何修改都会影响这两个变量。 若要克隆对象,请使用 Object.assign() 方法,该方法会将一个或多个源对象的所有可枚举属性的值复制到目标对象,但是此方法仅对对象的一个浅拷贝。

代码语言:javascript
复制
// 示例1
const names = {
  name: '前端小智',
  surname: '隔壁老智'
}

const names2 = names;
console.log(names, names2) // 打印结果是一模一样的

// 示例2
names2.surname ='隔壁老王';
console.log(names, names2)

// {name: "前端小智", surname: "隔壁老王"}
// {name: "前端小智", surname: "隔壁老王"}

// 示例3
const names3 = Object.assign({}, names);
names3.surname = '隔壁老色P';
console.log(names, names3)

// {name: "前端小智", surname: "隔壁老王"}
// {name: "前端小智", surname: "隔壁老色P"}

要对对象进行深拷贝,需要使用其他方法。

正如我们所说,Object.assign()方法只是一个浅拷贝(即,当我们的对象没有其他对象作为属性时)才有效。 在这些情况下,必须对对象进行深拷贝。

与浅拷贝不同,深拷贝以递归方式复制每个子对象,直到所有涉及的对象都被复制为止。

我们可以使用什么方法复制对象的深层副本?

JSON.parse(JSON.stringify(obj))

此方法使用JSON.stringify()将对象转换为字符串,然后再用JSON.parse()将其转换回对象。 此方法对简单对象有效,但如果对象属性是函数时无效。

代码语言:javascript
复制
const names = {
  name: '前端小智',
  surname: '隔壁老智',
  social: {
    wx: '大迁世界',
    url: 'www.lsp.com'
  }
}
const names2 = JSON.parse(JSON.stringify(names));
names2.social.url = 'www.baidu.com';
console.log(names, names2);

/** 
{
  name: "前端小智"
  social: {wx: "大迁世界", url: "www.lsp.com"}
  surname: "隔壁老智"
}
*/

/** 
{
  name: "前端小智"
  social: {wx: "大迁世界", url: "www.baidu.com"}
  surname: "隔壁老智"
}
*/

深度拷贝

另一种非常有趣和优雅的对象深度复制方法是使用递归函数。

我们创建了一个deepClone(object)函数,将想要克隆的对象作为参数传递给它。在函数内部,将创建一个局部变量克隆,这是一个空对象,其中将从起始对象克隆的每个属性都将添加到该对象中。

具体思路:

  • 如果该属性不是对象,则将其简单地克隆并添加到新的克隆对象中。
  • 如果属性是对象,则再次执行deepClone(value)函数,并将属性的值(在这种情况下为对象)作为参数传递,并重复相同的过程。
代码语言:javascript
复制
function deepClone(object) {
  var clone = {};
  for (var key in object) {
    var value = object[key];
    if (typeof(value) !== 'object') {
      clone[key] = value;
    } else {
      clone[key]=deepClone(value);
    }
  }
  return clone;
} 

deepClone({value1:1,value2:{value3:2}});
//{value1:1,value2:{value3:2}}
deepClone({value1:1,value2:{value3:{value3b:3}}});
//{value1:1,value2:{value3:{value3b:3}}}

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug

原文:https://www.ma-o.org/en/progr...

交流

本文 GitHub https://github.com/qq44924588... 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 原始值
  • 引用值
  • 数组
  • 对象
  • JSON.parse(JSON.stringify(obj))
  • 深度拷贝
  • 交流
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档