浅拷贝与深拷贝
- 针对对象
深拷贝和浅拷贝只针对像 Object
, Array
这样的复杂对象的,String
,Number
等简单类型不存在深拷贝。
- 浅拷贝
因为浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制。在JavaScript中,对于Object
和Array
这类引用类型值,当从一个变量向另一个变量复制引用类型值时,这个值的副本其实是一个指针,两个变量指向同一个堆对象,改变其中一个变量,另一个也会受到影响。所以浅拷贝会导致 obj.arr
和 shallowObj.arr
指向同一块内存地址,当修改obj.arr
的值时,shallowObj.arr
的值同样会被修改,大概的示意图如下:
![](http://upload-images.jianshu.io/upload_images/3706166-0cad6f9259185302.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/646/format/webp)
- 深拷贝
而深拷贝则不同,它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深拷贝的方法递归复制到新对象上。这就不会存在上面 obj
和 shallowObj
的 arr
属性指向同一个对象的问题。当修改obj.arr
的值时,shallowObj.arr
的值不会被修改,仍然为原值,如下图:
![](http://upload-images.jianshu.io/upload_images/3706166-6b1d83bd23e8262a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/720/format/webp)
JSON.parse()和JSON.stringfy()
-
JSON.parse()
就是将JSON字符串解析成字符串描述的JavaScript值或对象,例如:
JSON.parse('{}'); // {}
JSON.parse('true'); // true
JSON.parse('"foo"'); // "foo"
JSON.parse('[1, 5, "false"]'); // [1, 5, "false"]
JSON.parse('null'); // null
-
JSON.stringfy()
是JSON.parse()
的反义,就是将一个JavaScript值(对象或者数组)转换为一个JSON字符串,例如:
JSON.stringify({}); // '{}'
JSON.stringify(true); // 'true'
JSON.stringify("foo"); // '"foo"'
JSON.stringify([1, "false", false]); // '[1,"false",false]'
JSON.stringify({ x: 5 }); // '{"x":5}'
JSON.parse()官方解释
JSON.stringfy()官方解释
深拷贝方法——JSON.parse(JSON.stringfy())
- 用法
JOSN对象中的stringify
可以把一个js对象序列化为一个JSON字符串,parse
可以把JSON字符串反序列化为一个js对象,通过这两个方法,也可以实现对象的深复制。
function jsonClone(obj) {
return JSON.parse(JSON.stringify(obj));
}
var clone = jsonClone({ a:1 });
- 弊端
用法简单,然而使用这种方法会有一些隐藏的坑:因为在序列化JavaScript对象时,所有函数和原型成员会被有意忽略。
通俗点说,JSON.parse(JSON.stringfy(X))
,其中X只能是Number
, String
, Boolean
, Array
, 扁平对象,即那些能够被 JSON 直接表示的数据结构。
浅拷贝的实现
var shallowCopy = function(obj){
// only copy obj
if(typeof obj !== 'object') return;
// 根据obj的类型判断是数组还是对象
var newObj = obj instanseof Array ? [] : {};
//遍历obj,判断是obj的属性才copy
for(var key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = obj[key];
}
}
return newObj;
}
ES6的新方法
1.
let [...spread]= [12, 5, 8, 130, 44];
//等同于:let spread = 浅克隆([12, 5, 8, 130, 44])
Array.from(array)//创建一个新数组
深拷贝的实现
var deepCopy = function(obj){
if (typeof obj !== 'object' ) return;
var newObj = obj instanceof Array ? [] : {};
for(var key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key];
}
}
return newObj;
}
THE END
转自:https://www.jianshu.com/p/68e563c54f63