工作日常--js引用类型数据深拷贝与浅拷贝
2017-12-07 17:21
447 查看
js数据类型
简单数据类型简单的数据类型包括
Undifine,NULL,Bolean,String,Number。这些数据类型的数据的保存是在堆中存储的。堆中存放的数据是先进先出。FIFO(first in first out)
引用类型
引用类型包括Object和Array,引用数据类型是存放在栈中的。栈中存放的数据是先进后出的。FILO(frist in last out)
关于js的浅拷贝和深拷贝
++只有引用数据类型才会有深拷贝和浅拷贝这么一说。由于js的存储都是存地址的,浅拷贝会导致obj1和obj2指向同一个内存地址。这么一来,如果操作其中的任意一个obj那么就会导致元内存地址的数据更改。所以需要使用到深拷贝,为拷贝出的对象开辟一块新的内存地址。这样一来,就会出现原对象与新拷贝的对象在不同的内存地址。从而达到前后对象相互不影响。++浅拷贝
数组的浅拷贝var oldArray = [1,2,3,4,5,6]; var newArray = []; newArray = oldArray; newArray[0] = '改变的元素'; console.log(oldArray); // '改变的元素',2,3,4,5,6 console.log(newArray); // '改变的元素',2,3,4,5,6
对象的浅拷贝
function copyObject(obj){ var outObj = {}; for(var item in obj){ outObj.item = obj[item]; } return outObj; } // Object.assign() 将元对象的属性枚举到新的对象,然后返回新的对象 var obj = { name:'二货', sex:'male', age:23 } var b = {}; Object.assign(b,obj); if(b === obj) // true
深拷贝
数组的concat与slice方法(假装深拷贝)++concat与slice方法都是浅拷贝一个数组的元素然后拷贝给一个新的数组。只是如果数组的单个元素是数字,字符串等简单数据类型的时候,原数组的对象不会受新数组的影响。如果数组的项是引用类型数组或对象,则就是浅拷贝。++
var origin = [1,2,3,4,5]; var copySlice = origin.slice(0); var copyConcat = origin.concat(); copySlice[0] = 'one'; copyConcat[0] = 'concat'; console.log(origin); // [1,2,3,4,5]
var origin = [[1,2,3],{name:'lol'}]; var copySlice = origin.slice(0); var copyConcat = origin.concat(); copySlice[0][0] = 'slice'; copyConcat[1].name = 'concat'; console.log(origin) // [['slice',2,3],{name:'concat'}]
深拷贝实现方法JSON.parse和JSON.stringify();
这种方法使用较为简单,可以满足基本的深拷贝需求,而且能够处理JSON格式能表示的所有数据类型,但是对于正则表达式类型、函数类型等无法进行深拷贝(而且会直接丢失相应的值)。还有一点不好的地方是它会抛弃对象的constructor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。同时如果对象中存在循环引用的情况也无法正确处理。
//例1 var source = { name:"source", child:{ name:"child" } } var target = JSON.parse(JSON.stringify(source)); target.name = "target"; //改变target的name属性 console.log(source.name); //source console.log(target.name); //target target.child.name = "target child"; //改变target的child console.log(source.child.name); //child console.log(target.child.name); //target child //例2 var source = { name:function(){console.log(1);}, child:{ name:"child" } } var target = JSON.parse(JSON.stringify(source)); console.log(target.name); //undefined //例3 var source = { name:function(){console.log(1);}, child:new RegExp("e") } var target = JSON.parse(JSON.stringify(source)); console.log(target.name); //undefined console.log(target.child); //Object {}
相关文章推荐
- JS中的两种数据类型及实现引用类型的深拷贝的方法
- 浅谈js基础数据类型和引用类型,深浅拷贝问题,以及内存分配问题
- js基本数据类型引用类型深复制浅复制
- React引用数据类型与immutable.js的使用实例
- 详解JS数据类型的值拷贝函数(深拷贝)
- JS基本数据类型和引用类型的参数传递详细分析
- js基本数据类型和引用类型交换传值
- JS解决浮点数据类型的计算(引用)
- js中的栈与堆的讲解/基本数据类型与引用类型的讲解
- Js从头学起(详细分析基本数据类型和引用类型的参数传递)
- JS 对 基本数据类型 和 引用类型 的判断
- js 数据引用类型(二)——数组Array
- js数据类型 ——引用类型(Array).2/3
- Js 基本数据类型、引用数据类型
- Js从头学起(基本数据类型和引用类型的参数传递详细分析)
- js数据类型以及深拷贝浅拷贝总结
- Javascript小知识点(七):数据类型赋值,浅拷贝,深拷贝(数组值传递还是引用传递)
- Js 基本数据类型、引用数据类型
- JS基本数据类型和引用数据类型的区别
- js--3.对象-2.基本和引用数据类型