JavaScript深拷贝、浅拷贝
栏目: JavaScript · 发布时间: 5年前
内容简介:浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变。深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变。
JavaScript深拷贝、浅拷贝
浅拷贝:浅拷贝只是复制了内存地址,如果原地址中的对象改变了,浅拷贝出来的对象也会相应改变。
深拷贝:开辟了一块新的内存存放地址和地址指向的对象,原地址的任何对象改变了,深拷贝出来的对象不变。
浅拷贝数组(只拷贝第一级数组):
1.直接遍历
var arr = [1,2,3,4]; function copy(arg){ var newArr = []; for(var i = 0; i < arr.length; i++) { newArr.push(arr[i]); } return newArr; } var newArry = copy(arr); console.log(newArry); newArry[0] = 10; console.log(newArry); // [10,2,3,4] console.log(arr) // [1,2,3,4]
2.slice
var arr = [1,2,3,4] var copyArr = arr.slice(); copyArr[0] = 10; console.log(copyArr); // [10,2,3,4] console.log(arr); // [1,2,3,4]
slice(start,end) , slice()
方法返回一个数组中复制出来的元素组成新数组, start
指起始元素下标,end指终止元素下标
当 slice()
不带任何参数时,默认返回一个和原数组一样的新数组
3.concat()
var arr = [1,2,3,4] var copyArr = arr.concat(); copyArr[0] = 10; console.log(copyArr); // [10,2,3,4] console.log(arr); // [1,2,3,4]
array.concat(array1,array2,.......,arrayN) , concat()
方法用于连接两个或多个数组(不会改变原数组,返回被连接数组的副本)
然而如果第一级数组元素是对象或数组,上面三种方式都失效:
var arr = [ {number:1}, {number:2}, {number:3} ] var copyArr = arr.slice(); copyArr[0].number = 10; console.log(copyArr); // [{number: 100}, { number: 2 },{ number: 3 }] console.log(arr); // [{number: 100}, { number: 2 }, { number: 3 }]
浅拷贝对象(如果对象中的值不为数组或对象)
1.直接遍历
var obj = { name: "张三", job: "学生" } function copy (arg) { let newobj = {} for(let item in obj) { newobj[item] = obj; } return newobj; } var copyobj = copy(obj) copyobj.name = "李四" console.log(copyobj) // {name: '李四', job:: '学生'} console.log(obj) // {name: '张三', job:: '学生'}
2.ES6的Object.assign
var obj = { name: '张三', job: '学生' } var copyobj = Object.assign({},obj) copyobj.name = '李四' console.log(copyobj) // {name: '李四', job:: '学生'} console.log(obj) // {name: '张三', job:: '学生'}
Object.assign:用于对象的合并,将源对象 (source)
的所有可枚举属性,复制到目标对象 (target)
,并返回合并后的 target
用法: Object.assign(target, source1, source2) ; 所以 copyObj = Object.assign({}, obj) ; 这段代码将会把 obj
中的一级属性都拷贝到 {}
中,然后将其返回赋给 copyObj
3.ES6扩展运算符
var obj = { name: '张三', job: '学生' } var copyobj = {...obj} copyobj.name = '李四' console.log(copyobj) console.log(obj)
扩展运算符 (...)
用于取出参数对象的所有可遍历属性,拷贝到当前对象之中
深拷贝
JSON.stringify()
和 JSON.parse()
用 JSON.stringify
把对象转成字符串,再用 JSON.parse
把字符串转成新的对象。
但是这种方法也有不少坏处,譬如它会抛弃对象的 constructor
。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成 Object
。
这种方法能正确处理的对象只有 Number
, String
, Boolean
, Array
, 扁平对象,即那些能够被 json
直接表示的数据结构。 RegExp
对象是无法通过这种方式深拷贝。
也就是说,只有可以转成 JSON
格式的对象才可以这样用,像 function
、 undefined
、 symbol
、循环引用的对象没办法转成 JSON
。
var obj1 = { fun: function(){ console.log(123) } }; var obj2 = JSON.parse(JSON.stringify(obj1)); console.log(typeof obj1.fun); // 'function' console.log(typeof obj2.fun); // 'undefined' <-- 没复制
使用递归函数实现一个深拷贝的方法:
function deepClone(obj) { let objClone = Array.isArray(obj) ? [] : {}; if(obj && typeof obj === "object") { for(key in obj) { if(obj.hasOwnProperty(key)) { if(obj[key] && typeof obj[key] === "object") { objClone[key] = deepClone(obj[key]); } else { objClone[key] = obj[key]; } } } } return objClone }
以上所述就是小编给大家介绍的《JavaScript深拷贝、浅拷贝》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
JS 压缩/解压工具
在线压缩/解压 JS 代码
RGB CMYK 转换工具
RGB CMYK 互转工具