📕 重学JavaScript: 需要注意哪些方法是浅拷贝,不要在代码中滥用?

简介: 嗨,大家好!这里是`道长王jj`~ 🎩🧙‍♂️今天来和大家聊聊关于浅拷贝的相关知识。

📕 重学JavaScript: 需要注意哪些方法是浅拷贝,不要在代码中滥用?

嗨,大家好!这里是道长王jj~ 🎩🧙‍♂️

今天来和大家聊聊关于浅拷贝的相关知识。

❓ 什么是浅拷贝

其实很简单,就是把一个东西复制一份,然后给另一个东西。😁

比如,你有一个数组叫 arr ,它里面有三个元素,就像这样:

let arr = [1, 2, 3];

然后,你想把这个数组给 newArr ,你可以这样写:

let newArr = arr;

这样,newArr 就和 arr 一样了。😊

但是,这样有一个问题,就是 newArr 和 arr 其实是同一个东西,只不过换了个名字而已。也就是说,它们指向的是同一块内存空间。😮

所以,如果你改变了 newArr 的内容,比如这样:

newArr[0] = 100;

那么,arr 的内容也会跟着改变,就像这样:

console.log(arr);//[100, 2, 3]

这时候,你可能想要的是 newArr 和 arr 是两个不同的东西,它们只是内容相同而已。也就是说,它们指向的是不同的内存空间。😁

这时候,你就需要用到拷贝了。拷贝就是把一个东西的内容复制一份,并放到另一个新的东西里。😊

比如,你可以用数组的 slice 方法来实现拷贝,就像这样:

let newArr = arr.slice();

这样,newArr 就和 arr 的内容一样了,但是它们不是同一个东西了。😊

所以,如果你改变了 newArr 的内容,比如这样:

newArr[0] = 100;

那么,arr 的内容不会跟着改变,就像这样:

console.log(arr);//[1, 2, 3]

这种拷贝叫做浅拷贝。浅拷贝只能复制对象的第一层属性,而不复制对象的深层属性。

也就是说,如果对象的属性是基本类型(数字、字符串、布尔值等),那么就直接复制这个值

如果对象的属性是引用类型(数组、对象、函数等),那么就复制这个引用(指针),而不复制引用指向的对象。😮

所以,浅拷贝有一个潜在的问题,就是如果对象里有嵌套的对象或数组,那么浅拷贝就无能为力了。比如这样:

let arr = [1, 2, {
   val: 4}];
let newArr = arr.slice();
newArr[2].val = 1000;

console.log(arr);//[ 1, 2, { val: 1000 } ]

咦!不是已经不是同一块空间的引用了吗?为什么改变了newArr改变了第二个元素的val值,arr也跟着变了。

这就是浅拷贝的限制所在了。它只能拷贝一层对象。如果有对象的嵌套,浅拷贝就无法实现完全的拷贝。😭

这一期我们先重点关注浅拷贝的实现方法。

❓ 我需要注意哪些方法是浅拷贝呢?

现在你有一个对象叫obj,它里面有几个属性,就像这样:

let obj = {
   
  a: 1,
  b: 2,
  c: [3, 4]
};

第一种:手动遍历赋值

let newObj = {
   };
for (let key in obj) {
   
  // 判断属性是否是自身的
  if (obj.hasOwnProperty(key)) {
   
    // 把属性赋值给新对象
    newObj[key] = obj[key];
  }
}

第二种:用 Object.assign 方法

这个方法可以把一个或多个源对象的属性复制到目标对象上,并返回目标对象。

这个方法比较方便,但是要注意它只能复制可枚举的属性,而且如果源对象的属性是 getter 函数,那么它会执行这个函数,并把返回值赋给目标对象。

let newObj = Object.assign({
   }, obj);

第三种:数组的 concat 方法

这个方法可以把一个或多个数组连接起来,并返回一个新的数组。

这个方法可以实现数组的浅拷贝,但是要注意它只能处理数组,而且如果数组里有引用类型的元素,那么它也只会复制引用。

let newArr = arr.concat();

第四种:数组的 slice 方法

这个方法可以返回一个数组的一部分,并返回一个新的数组。

这个方法也可以实现数组的浅拷贝,但是要注意它也只能处理数组,而且如果数组里有引用类型的元素,那么它也只会复制引用。

let newArr = arr.slice();

第五种:扩展运算符

这个运算符可以把一个可迭代对象展开成多个元素,并放在一个新的数组或对象里。

这个运算符可以实现数组或对象的浅拷贝,但是要注意它也只能复制可枚举的属性,而且如果源对象或数组里有引用类型的元素或属性,那么它也只会复制引用。

let newArr = [...arr];
let newObj = [...obj];

🎉 你觉得怎么样?这篇文章可以给你带来帮助吗?如果你有任何疑问或者想进一步讨论相关话题,请随时发表评论分享您的想法,让其他人从中受益。🚀✨

目录
相关文章
|
5月前
|
监控 负载均衡 JavaScript
有哪些有效的方法可以优化Node.js应用的性能?
有哪些有效的方法可以优化Node.js应用的性能?
306 69
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法详解
本指南详细介绍在Linux系统中安装和管理Node.js的步骤。首先检查现有环境,包括查看当前版本和清除旧版本;接着通过NodeSource仓库安装最新版Node.js并验证安装结果。推荐使用nvm(Node Version Manager)进行多版本管理,便于切换和设置默认版本。同时,提供常见问题解决方法,如权限错误处理和全局模块迁移方案,以及版本回滚操作,确保用户能够灵活应对不同需求。
336 0
|
27天前
|
JavaScript 前端开发 安全
【逆向】Python 调用 JS 代码实战:使用 pyexecjs 与 Node.js 无缝衔接
本文介绍了如何使用 Python 的轻量级库 `pyexecjs` 调用 JavaScript 代码,并结合 Node.js 实现完整的执行流程。内容涵盖环境搭建、基本使用、常见问题解决方案及爬虫逆向分析中的实战技巧,帮助开发者在 Python 中高效处理 JS 逻辑。
|
4月前
|
JavaScript Linux 内存技术
Debian 11系统下Node.js版本更新方法
Debian 11更新Node.js主要就是这三种方式,无论你是初涉其中的新手还是找寻挑战的专家,总有一种方式能满足你的需求。现在,你已经是这个
371 80
|
3月前
|
JavaScript 前端开发 算法
流量分发代码实战|学会用JS控制用户访问路径
流量分发工具(Traffic Distributor),又称跳转器或负载均衡器,可通过JavaScript按预设规则将用户随机引导至不同网站,适用于SEO优化、广告投放、A/B测试等场景。本文分享一段不到百行的JS代码,实现智能、隐蔽的流量控制,并附完整示例与算法解析。
98 1
|
4月前
|
JavaScript 前端开发
怀孕b超单子在线制作,p图一键生成怀孕,JS代码装逼娱乐
模拟B超单的视觉效果,包含随机生成的胎儿图像、医疗文本信息和医院标志。请注意这仅用于前端开发学习
|
4月前
|
JavaScript
JS代码的一些常用优化写法
JS代码的一些常用优化写法
76 0
|
6月前
|
存储 JavaScript 前端开发
在NodeJS中使用npm包进行JS代码的混淆加密
总的来说,使用“javascript-obfuscator”包可以帮助我们在Node.js中轻松地混淆JavaScript代码。通过合理的配置,我们可以使混淆后的代码更难以理解,从而提高代码的保密性。
497 9
|
6月前
|
JavaScript 前端开发 Java
js 垃圾回收机制的方法
JS回收机制方法讲解
|
7月前
|
前端开发 JavaScript
【Javascript系列】Terser除了压缩代码之外,还有优化代码的功能
Terser 是一款广泛应用于前端开发的 JavaScript 解析器和压缩工具,常被视为 Uglify-es 的替代品。它不仅能高效压缩代码体积,还能优化代码逻辑,提升可靠性。例如,在调试中发现,Terser 压缩后的代码对删除功能确认框逻辑进行了优化。常用参数包括 `compress`(启用压缩)、`mangle`(变量名混淆)和 `output`(输出配置)。更多高级用法可参考官方文档。
506 11

热门文章

最新文章