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

我们可以利用 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. (Python基础)列表的认知

    以下是列表的一些知识点 name = ['关羽','张飞','刘备','曹操','诸葛亮','吕布',['吕布','吕布',],'吕布','吕布','吕布','吕布']for i in name: p ...

  2. rsync:基本命令和用法

    以下是rsync系列篇: 1.rsync(一):基本命令和用法 2.rsync(二):inotify+rsync详细说明和sersync 3.rsync算法原理和工作流程分析 4.rsync技术报告( ...

  3. mysql导入excel表格

    https://jingyan.baidu.com/album/fc07f9891cb56412ffe5199a.html?picindex=1

  4. Mysql将查询结果合并为一列

    利用函数:group_concat(),实现一个ID对应多个名称时,原本为多行数据,把名称合并成一行. 完整的语法如下: group_concat([DISTINCT] 要连接的字段 [Order B ...

  5. pflag如何使用

    1 为何我对这个库感兴趣呢? 因为我想看看Kubernetes的源码,Kubernetes,Hugo啥的都是那这个解析的命令行参数 2 安装 go get github.com/spf13/pflag ...

  6. C罗转会尤文图斯

    皇家马德里头号球星C罗转会意甲尤文图斯,结束了9年的皇马生涯,已获得5座金球奖.

  7. CentOS 7设置yum仅仅下载rpm不安装总结

    前言 参考文章:https://linux.cn/article-7937-1.html 在参考文章的基础上进行总结. 使用download-only插件实现 首先我们可以使用downloadonly ...

  8. mongodb 多表查询

    今天有一个业务涉及到mongodb的多表查询,大体记录下语句结构 db.table_a.aggregate([ {$lookup:{from:"table_b",localFiel ...

  9. web移动端区分Android或者ios系统

    // 这里区分方式类似于区分不同浏览器, 这里是es6的写法,在react项目中使用过的. const ua = typeof window === 'object' ? window.navigat ...

  10. onenet简介

    物联科技|物联网开放平台探秘之移动OneNET平台(上) 物联科技 百家号17-07-1008:57 当前,国内外物联网行业发展如火如荼,众多传统行业也在谋求向物联网转型.许多电子工程师或出于个人意愿 ...