美文网首页IT修真院-前端
浅谈js数组深拷贝和浅拷贝

浅谈js数组深拷贝和浅拷贝

作者: lx2487 | 来源:发表于2017-08-19 10:03 被阅读0次

1.背景介绍

什么是栈内存和堆内存?

JavaScript中的变量的存放有有原始值与引用值之分,原始值代表了原始的数据类型,如Undefined,Null,Number, String,Boolean类型的值;而Object,Function,Array等类型的值便是引用值了。

栈内存中存放的是存储对象的地址,而堆内存中存放的是存储对象的具体内容。对于原始类型的值而言 ,其地址和具体内容都存在与栈内存中;而基于引用类型的值,其地址存在栈内存,其具体内容存在堆内存中。堆内存 与栈内存是有区别的,栈内存运行效率比堆内存高,空间相对堆内存来说较小,反之则是堆内存的特点。所以将构造简 单的原始类型值放在栈内存中,将构造复杂的引用类型值放在堆中而不影响栈的效率。

2.知识剖析

什么是深拷贝和浅拷贝?

浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。

深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。可以使用slice和concat方法。

SLICE和CONCAT使用方法

slice:

语法:arrayObject.slice(start,end)

该方法并不会修改数组,而是返回一个子数组。

start:必需。规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。也就是说,-1 指最后一个元素,-2 指倒数第二个元素,以此类推。

end:可选。规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果这个参数是负数,那么它规定的是从数组尾部开始算起的元素。

concat:

语法:arrayObject.concat(arrayX,arrayX,......,arrayX)

返回一个新的数组。该数组是通过把所有 arrayX 参数添加到 arrayObject 中生成的。如果要进行 concat() 操作的参 数是数组,那么添加的是数组中的元素,而不是数组。

arrayX:必需。该参数可以是具体的值,也可以是数组对象。可以是任意多个。

3.常见问题

深拷贝和浅拷贝的运用环境。

4.解决方案

这个要看大家具体的应用,注意到数组带来的影响。

5.编码实战

浅拷贝的实现,例如:

var arr = ["One","Two","Three"];

var arrto = arr; arrto[1] = "test”;

document.writeln("数组的原始值:" + arr + "

");//Export:数组的原始值:One,test,Three

document.writeln("数组的新值:" + arrto + "

");//Export:数组的新值:One,test,Three

深拷贝之slice:

var num = ["One","Two","Three"];

var newNum = num.slice(0);

newNum[1] = "haha";

document.writeln("数组的原始值:" + num + "

");//Export:数组的原始值:One,Two,Three

document.writeln("数组的新值:" + newNum + "

");//Export:数组的新值:One,haha,Three

深拷贝之concat

var arr = new Array(3)

arr[0] = "George"

arr[1] = "John"

arr[2] = "Thomas"

var arr2 = new Array(3)

arr2[0] = "James"

arr2[1] = "Adrew"

arr2[2] = "Martin"

document.write(arr.concat(arr2))//输出:George,John,Thomas,James,Adrew,Martin;

6.扩展思考

对象的深拷贝

对象自己写个迭代函数就好了,只需copy到最底层的比如如下代码。

function deepCopy(obj,c) {

var c =c || {};

for(var i in obj) {

// 判断属性是否为对象,是的话就进一步展开

if (typeof(obj[i]) === 'object') {

// 递归拷贝

if (obj[i].constructor == Array){

c[i] = [];

deepCopy(obj[i],c[i]);

}

else {

c[i] = {};

deepCopy(obj[i],c[i]);

}

}

else {

c[i] = obj[i];

}

}

return c

};

7.参考文献

参考一:JavaScript数组深拷贝和浅拷贝的两种方法

参考二:原生js对象的浅拷贝和深拷贝的总结

8.更多讨论

有被浅拷贝坑过的经历吗?

Q1:简述深拷贝和浅拷贝的最大不同?

A1:一个是复制粘贴(完全独立),一个是创建快捷方式(一个内存地址的不同引用)。

Q2:说出两个深拷贝的js方法。

A2:SLICE()和CONCAT()

Q3:堆内存与栈内存的区别?

A3:堆内存 与栈内存是有区别的,栈内存运行效率比堆内存高,空间相对堆内存来说较小,反之则是堆内存的特点。所以将构造简 单的原始类型值放在栈内存中,将构造复杂的引用类型值放在堆中而不影响栈的效率。


如何实现数组深拷贝和浅拷贝?_腾讯视频

PPT链接:PPT链接

视频链接:https://v.qq.com/x/page/r0539yabtmb.html

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

技能树.IT修真院

“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。快来与我一起学习吧 !

欢迎进入修真之旅!

相关文章

  • JS中对象的复制

    JS中的对象复制分为两种情况:深拷贝和浅拷贝。深拷贝和浅拷贝的区别在于对数组和对象的拷贝,对它们拷贝时浅拷贝只是拷...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • 浅谈js数组深拷贝和浅拷贝

    1.背景介绍 什么是栈内存和堆内存? JavaScript中的变量的存放有有原始值与引用值之分,原始值代表了原始的...

  • 关于几个拷贝的问题

    数组浅拷贝 数组深拷贝 复合数组深拷贝

  • js浅拷贝深拷贝

    js浅拷贝,深拷贝的简单实现 基础数据 浅拷贝 深拷贝

  • 浅拷贝和深拷贝

    本文参考:JavaScript中的浅拷贝和深拷贝js 深拷贝 vs 浅拷贝深入剖析 JavaScript 的深复制...

  • copy和mutablecopy

    Objective-C中的浅拷贝和深拷贝 - CocoaChina_让移动开发更简单 iOS 浅谈:深.浅拷贝与c...

  • 深拷贝和浅拷贝

    1: iOS开发 深拷贝与浅拷贝 2: iOS 浅谈:深.浅拷贝与copy.strong 3: iOS开发——深...

  • 手撕常见面试题

    DOM 事件代理 数组 对象 扁平化 去重 - unique() 拷贝 浅拷贝 深拷贝 copy()函数实现 JS...

  • JS实现深拷贝、instanceof、判断是否为数组

    JS深拷贝 JS中拷贝对象可以按照拷贝的程度可以分为浅拷贝和深拷贝,有些时候我们需要拷贝之后的对象和拷贝之前的对象...

网友评论

    本文标题:浅谈js数组深拷贝和浅拷贝

    本文链接:https://www.haomeiwen.com/subject/laxtdxtx.html