项目中根据各种需求或多或少会需要用到拷贝,通过查询整理之后今天简单的记录一下。

我们可以利用 slice、concat 返回一个新数组的特性可以实现数组的拷贝。

var arr = ['a', 1, true, null, undefined];
var new_arr = arr.concat();
console.log(arr) // ["a", 1, true, null, undefined]
console.log(new_arr) // ["a", 1, true, null, undefined] var arr = ['a', 1, true, null, undefined];
var new_arr = arr.slice();
console.log(arr) // ["a", 1, true, null, undefined]
console.log(new_arr) // ["a", 1, true, null, undefined]

我们会发现,无论是新数组还是旧数组都发生了变化,也就是说使用 concat 方法,克隆的并不彻底。这里可以联系值传递和引用传递、栈内存和堆内存的问题:如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。

那如何深拷贝一个数组呢?这里介绍一个技巧,不仅适用于数组还适用于对象!那就是:

var arr = ['a', 1, true, ['old1', 'old2'], {old: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );
console.log(arr);
console.log(new_arr);

以上三个方法 concat、slice、JSON.stringify 都算是技巧类,可以根据实际项目情况选择使用,接下来我们思考下如何实现一个对象或者数组的浅拷贝。

浅拷贝的实现:

遍历对象,然后把属性和属性值都放在一个新的对象就好了

var copy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
var arr = [{a:"1"},["2"]];
var newarr = copy (arr);
console.log(newarr);//[{a:"1"},["2"]]

深拷贝的实现

我们在浅拷贝的时候判断一下属性值的类型,如果是对象,我们递归调用浅拷贝函数

var deepCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
/* if(typeof obj[key] === "object"){
newObj[key] = deepCopy(obj[key]);
}else{
newObj[key] = obj[key];
}*/
newObj[key] = typeof obj[key] === "object" ? deepCopy(obj[key]) : obj[key]
}
}
return newObj;
}
var arr = [{a:"1"},["2"]];
var newarr = deepCopy(arr);
console.log(newarr);//[{a:"1"},["2"]]

性能问题

尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。

JS的深浅拷贝的更多相关文章

  1. JS中深浅拷贝 函数封装代码

    一.了解 基本数据类型保存在栈内存中,按值访问,引用数据类型保存在堆内存中,按址访问. 二.浅拷贝 浅拷贝只是复制了指向某个对象的指针,而不是复制对象本身,新旧对象其实是同一内存地址的数据,修改其中一 ...

  2. 两行代码搞定js对象深浅拷贝

    有一段时间没有更新博客了,忙于工作.2018年刚过去,今天来开启2018第一篇博文.好了,咱们步入正题. 先上代码 /** * 遍历对象 * 1.判断是不是原始值 * 2.判断是数组还是对象 * 3. ...

  3. JS实现深浅拷贝

    1.实现浅拷贝 // 1. ...实现 let copy1 = {...{x:1}} // 2. Object.assign实现 let copy2 = Object.assign({}, {x:1} ...

  4. JS复习之深浅拷贝

    一.复习导论(数据类型相关) 想掌握JS的深浅拷贝,首先来回顾一下JS的数据类型,JS中数据类型分为基本数据类型和引用数据类型. 基本数据类型是指存放在栈中的简单数据段,数据大小确定,内存空间大小可以 ...

  5. JS--变量及深浅拷贝

    JS变量分为基本类型和引用类型 基本类型数据包括Number, String, Boolean, Null, Undefined五种类型: 引用数据类型包括Array, Date, RegExp, F ...

  6. javascript简单实现深浅拷贝

    深浅拷贝知识在我们的日常开发中还算是用的比较多,但是之前的状态一直都是只曾听闻,未曾使用(其实用了只是自己没有意识到),所以今天来跟大家聊一聊js的深浅拷贝: 首先我们来了解一下javascript的 ...

  7. 【 js 基础 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

  8. 【 js 基础 】【 源码学习 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

  9. js 基础数据类型和引用类型 ,深浅拷贝问题,以及内存分配问题

    js 深浅拷贝问题 浅拷贝一般指的是基本类型的复制 深拷贝一般指引用类型的拷贝,把引用类型的值也拷贝出来 举例 h5的sessionStorage只能存放字符串,所以要存储json时就要把json使用 ...

随机推荐

  1. python3 摘抄

    https://www.python.org/downloads/release/python-370/ python3.7.0 win10环境,选:Windows x86-64可执行安装程序. ht ...

  2. Springboot整合druid

    目录 Springboot整合druid application.yml DruidConfig 数据监控地址:http://localhost:8080/druid Springboot整合drui ...

  3. html页面嵌套两个iframe页面导致第二个iframe页面高度失效的问题

    1:这是因为最里面嵌套的iframe页面html和body高度无法设置问题,我的解决办法是js去控制iframe高度 2:js获取最子页面(content内容区域)的高度 var ifremHeigh ...

  4. 每日算法之递推排序(P1866 编号)

    兔子也是数字控:每个兔子都有自己喜欢的数字区间,找出能让所有兔子都满意的组合. 将所有兔子喜欢的序号按从小到大排序,此时如果小序号的兔子选择了一个数字,则之后的兔子只要排除排在它之前的兔子数(由于已经 ...

  5. nginx优化php-fpm优化 压力测试达到每分150万访问量webbench网站压力

    webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好,安装使用也特别方便. 1.适用系统:Linux 2.编译安装:引用wget http: ...

  6. 远程服务器设置Mysql的操作权限

    mysql -u root -p; root用户输入密码登录mysql服务器 select host, user  from mysql.user; 查询数据库的所有用户以前权限的ip   host: ...

  7. python day03笔记总结

    2019.3.29 S21 day03笔记总结 昨日回顾及补充 1.运算符补充 in not in 2.优先级 运算符与运算符之间也有优先级之分 今日内容 一.整型(int) py2 与 py3 的区 ...

  8. Maven工程控制台乱码问题(IDEA)

    转自https://blog.csdn.net/love_live2/article/details/79311978 个人推荐使用文章中介绍的第三种方法,感觉挺好用的

  9. 安装软件,遇到弹框Windows Installer Coordinator,一直循环卡在这个弹框处

    转载自https://www.cliftonsystems.co.uk/fixing-windows-installer-coordinator-loop/ 复制粘贴原文内容,以防将来访问不到原网页了 ...

  10. MySQL编码不一致导致查询结果为空

    升级数据库后(5.1到8.0),发现一个奇怪的问题,某些页面在升级前可以正常查询,但升级后什么也查不出来了,有时候还会查出错误的结果.经过一整天的排查,终于发现由两个原因导致,现记录如下. 第一是数据 ...