最简js深浅拷贝说明
Posted ypm_wbg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最简js深浅拷贝说明相关的知识,希望对你有一定的参考价值。
1.浅拷贝
浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会互相影响。
浅拷贝分两种情况:
1、直接拷贝源对象的引用
2、 源对象拷贝实例,但其属性对象(类型为Object
,Array
的属性)拷贝引用
直接拷贝源对象的引用
//最简单的例子
var a = {c:1}; var b = a; console.log(a === b); // 输出true。 a.c = 2; console.log(b.c); // 输出 2,,这里就是拷贝了对象的引用,从而两边都改变了
源对象拷贝实例,其属性对象拷贝引用
说明:外层源对象是拷贝实例,当其属性元素为复杂数据类型时,内层元素拷贝引用。这时对源对象直接操作,不影响两对象,但是对其属性操作时候,会改变两对象的属性的值。
常用方法为:Array.prototype.slice()
, Array.prototype.concat()
, jQury
的$.extend({},obj)
var a = [{c:1}, {d:2},2]; var b = a.slice(); console.log(a === b); // 输出false,说明外层数组拷贝的是实例 a[0].c = 3; console.log(b[0].c); // 输出 3,说明其元素拷贝的是引用
a[2]=4;
console.log(b[2]); //输出 2,不是复杂数据类型,所以没有变,没有引用
2.深拷贝
将重新分配内存,并且把源对象所有属性都进行新建拷贝,以保证对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响。
深拷贝
说明:深拷贝后,两个对象,包括其内部的元素互不干扰。常见方法有JSON.parse()
,JSON.stringify()
,jQury
的$.extend(true,{},obj):
b = JSON.parse( JSON.stringify(a) )//最简单的深拷贝
但有局限性:
- 无法复制函数
- 原型链没了,对象就是object,所属的类没了
jQury
的$.extend(true,{},obj):
var a = {c: {d: 1}}; var b = $.extend(true, {}, a); console.log(a === b); // 输出false a.c.d = 3; console.log(b.c.d); // 输出 1,没有改变。
深拷贝本质理解:将原对象各个属性所包含的对象也依次采用深复制的方法“递归复制”到新对象上。这就不会存在上面 obj 和 shadowObj 的 arr 属性指向同一个对象的问题。例:
var deepCopy= function(source) { var result={}; for (var key in source) { result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key]; } return result; }//通过递归调用复制对对象上的每一个子类进行复制,从而达到时属性指向不同对象
复杂全面的代码,可以学习借鉴
function() { function _type(value) { return Object.prototype.toString.call(value).slice(8).slice(0, -1).toLowerCase(); } function isArray(value) { return _type(value) == ‘array‘; } function isObject(value) { return _type(value) == ‘object‘; } function cloneArray(src, dest) { src.forEach(function(item, index) { if (isArray(item)) { console.log(‘yes‘) dest[index] = []; copy(src[index], dest[index]); } else { dest[index] = src[index]; } }); } function cloneObject(src, dest) { for (var key in src) { // filter 原型链上面的属性 if (src.hasOwnProperty(key)) { if (isObject(src[key])) { // 判断循环引用的问题 if (src[key] === src) { dest[key] = src; } else { dest[key] = {}; copy(src[key], dest[key]); } } else if (isArray(src[key])) { dest[key] = []; cloneArray(src[key], dest[key]) } else { dest[key] = src[key]; } } } } function cloneDeep(src) { if (isArray(src)) { var dest = []; cloneArray(src, dest); } if (isObject(src)) { var dest = {}; cloneObject(src, dest); } return dest; } window.clone = cloneDeep; })();
如有错误欢迎留言改正……
以上是关于最简js深浅拷贝说明的主要内容,如果未能解决你的问题,请参考以下文章