JS 数组以及对象的深拷贝总结
javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法
前言
在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝。如下图演示:
如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并不是我们所需要的结果。
因此,数组以及对象的深拷贝就是javascript的一个基本功了。
数组的深拷贝
条条大道通罗马,实现数组的深拷贝,是有好几种方法的。举例如下:
for 循环实现数组的深拷贝
for循环是非常好用的。如果不知道高级方法,通过for循环能够完成我们大多数的需求。
var arr = [1,2,3,4,5]
var arr2 = copyArr(arr)
function copyArr(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
res.push(arr[i])
}
return res
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
如上,通过对数组的for循环,即可实现对数组的深拷贝了。
slice 方法实现数组的深拷贝
这个代码实现非常简单。原理也比较好理解,他是将原数组中抽离部分出来形成一个新数组。我们只要设置为抽离全部,即可完成数组的深拷贝。代码如下:
var arr = [1,2,3,4,5]
var arr2 = arr.slice(0)
arr[2] = 5
console.log(arr)
console.log(arr2)
- 1
- 2
- 3
- 4
- 5
运行结果如下:
更多 slice 内容请访问 w3school JavaScript slice 方法
concat 方法实现数组的深拷贝
这个代码也非常简单,原理更加粗暴。它是用于连接多个数组组成一个新的数组的方法。那么,我们只要连接它自己,即可完成数组的深拷贝。代码如下:
var arr = [1,2,3,4,5]
var arr2 = arr.concat()
arr[2] = 5
console.log(arr)
console.log(arr2)
- 1
- 2
- 3
- 4
- 5
运行结果如下:
更多 concat 内容请访问 w3school JavaScript concat 方法
2017年10月31日补充:ES6扩展运算符实现数组的深拷贝
OK,以上之前讲的方法全部过时了,用下面的方法实现数组的深拷贝是最简单的。
var arr = [1,2,3,4,5]
var [ ...arr2 ] = arr
arr[2] = 5
console.log(arr)
console.log(arr2)
- 1
- 2
- 3
- 4
- 5
运行结果如下:
对象的深拷贝
对象的深拷贝相比数组也没有困难许多,列举两个方法。
万能的for循环实现对象的深拷贝
在很多时候,for循环能够解决大问题。
var obj = {
name: 'FungLeo',
sex: 'man',
old: '18'
}
var obj2 = copyObj(obj)
function copyObj(obj) {
let res = {}
for (var key in obj) {
res[key] = obj[key]
}
return res
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
转换成json再转换成对象实现对象的深拷贝
上面的代码实在是比较长,所以,用一个更暴力的方法吧!代码如下:
var obj = {
name: 'FungLeo',
sex: 'man',
old: '18'
}
var obj2 = JSON.parse(JSON.stringify(obj))
- 1
- 2
- 3
- 4
- 5
- 6
这个原理没什么好解释的,实在是够简单粗暴的啦!
2017年10月31日补充: 扩展运算符实现对象的深拷贝
var obj = {
name: 'FungLeo',
sex: 'man',
old: '18'
}
var { ...obj2 } = obj
obj.old = '22'
console.log(obj)
console.log(obj2)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
运行结果如下:
小结
数组和对象的深拷贝是js中最常见的应用。理解各种方法是必须的。希望对大家有所帮助。
本文中并没有对异常进行处理,主要在讲原理。更多的数组以及对象的操作方法,可以参考lodash的源码,查看它的源码可以让你的js基础变得非常牢固。我也在学习中。
2017年10月31日补充,使用es6提供的扩展运算符的方法实现深拷贝,简单,高效。并且,对象的深拷贝不会像使用
JSON方法深拷贝一样,丢失函数等信息,只能用来深拷贝JSON数据格式的对象。推荐大家使用。
补充一个数组去重的方法
function dedupe(array) {
return [...new Set(array)]
}
var arr = [1,2,2,3,3,4,4,5,5]
console.log(dedupe(arr))
- 1
- 2
- 3
- 4
- 5
运行结果如下:
JS 数组以及对象的深拷贝总结的更多相关文章
- JS 数组、对象的深拷贝
博客地址:https://ainyi.com/72 JavaScript 程序中,对于简单的数字.字符串可以通过 = 赋值拷贝 但是对于数组.对象.对象数组的拷贝,就有浅拷贝和深拷贝之分 浅拷贝就是当 ...
- javascript 数组以及对象的深拷贝(复制数组或复制对象)的方法
前言 for,slice(0),concact() 在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝.如下图演示: 如上,arr的修改,会影响arr2的值,这显然在绝大多数情况下,并不 ...
- js 数组、对象转json 以及 json转 数组、对象
let jsonObj = $.parseJSON(jsonStr); //json字符串转化成json对象(jq方法) var jsonObj = JSON.parse(jsonStr); //js ...
- JS数组和对象的浅拷贝和深拷贝
共勉~ 在许多编程语言中,传递参数和赋值是通过值的直接复制或者引用复制完成的.在JavaScript中,对于值是直接进行复制还是引用复制在语法上是没有区别的,完全是根据值的类型来决定的. 在JavaS ...
- js数组和对象相等判断、拷贝详解(结合几个现象讲解引用数据类型的趣事)
序言 最近遇到几个js引用数据类型造成的bug,今天结合bug详细分析一下,避免以后再犯,也希望能帮大家提个醒,强化js基本功. 目录 1.浅拷贝.深拷贝,解决变量赋值相互影响问题 2.判断2个数组. ...
- JS实现对对象的深拷贝
手动遍历对象拷贝 /** * 深拷贝 * @param {*} obj 拷贝对象(object or array) * @param {*} cache 缓存数组 */ function deepCo ...
- js 数组、对象转json 以及json转 数组、对象
1.JS对象转JSON 方式:JSON.stringify(obj) var json = {"name":"iphone","price" ...
- JS数组与对象的遍历方法大全
本文简单解析各种数组和对象属性的遍历方法: 原生for循环.for-in及forEach ES6 for-of方法遍历类数组集合 Object.key()返回键名的集合 jQuery的$.each() ...
- js数组和对象的区别,ajax传入多个参数值,ajax传多个数组数据
数组分为索引数组和关联数组 js中先声明一个空数组 arr = [] 索引数组 索引是整数,如arr[0] = 'a' 关联数组 索引是自定义的字符串,如arr['a'] = 'a' js中的对象 你 ...
随机推荐
- 如何获取浏览器URL中查询字符串的参数?
如何获取浏览器URL中查询字符串的参数? 想要知道怎样解决这个问题,首先我们先认识一下Location对象. Location对象包含了当前页面与位置(url)相关的信息 URL示例:http://w ...
- Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
首先推荐一下鸿洋大大的打造个性的图片预览与多点触控视频教程,这套教程教我们一步一步实现了多点触控实现对图片的平移和缩放的功能.这篇文章我将在鸿洋大大的基础之上做了一些扩展功能: 1.图片的惯性滑动 2 ...
- PHP封装成应用程序的三个方案
大概有三个解决方案吧. 1 如果你精通PHP,你可以看看这个网站:http://gtk.php.net/ 很明显,这个网站介绍了啥是GTK,你可以构件跨平台的图形化应用程序,当然你要再学一门语言,去掌 ...
- python的加密模块(md5,sha,crypt)学习
python的加密模块(md5,sha,crypt)学习 命令行使用python MD5: yinguicai@Cpl-IBP-Product:~/data/work/svn/v1.4.0_dev/A ...
- NGUI Tutorial 4 ScrollView
一.createScrollView 1.First, select the panel you want to be your scroll view and right-click anywher ...
- Selenium中定位元素的方法
find_element_by_id()find_element_by_name()find_element_by_class_name()find_element_by_tag_name()find ...
- js 多级联动(省、市、区)
js 多级联动(省.市.区) CreateTime--2018年4月9日17:10:38 Author:Marydon 方式一: 数据从数据库获取,ajax实现局部刷新 方式二: 数据从json文 ...
- Servlet 异常处理
当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置.您必须在 web.xml 中使用 error-pa ...
- jenkins+gitlab钩子+shell脚本基于git的tag实现App增量更新
转自:http://blog.csdn.net/kingboyworld/article/details/54175330 环境安装 jdk1.8 1.安装jenkins 首先到https://jen ...
- Linux操作系统中多线程的同步
1 互斥锁 互斥锁用来保证一段时间内只有一个线程在执行一段代码.必要性显而易见:假设各个线程向同一个文件顺序写入数据,最后得到的结果一定是灾难性的. 先看下面一段代码.这是一个读/写程序,它们公用一个 ...