深拷贝和浅拷贝
浅拷贝是一个传址,
也就是把a的值赋给b的时候同时也把a的址赋给了b,
当b(a)的值改变的时候,a(b)的值同时也会改变
深拷贝:拷贝对象的具体内容,内存地址是自主分配的。
拷贝结束之后俩个对象虽然存的值是一样的,但是内存地址不一样。
俩个对象页互相不影响,互不干涉
浅拷贝
(1)遍历赋值实现
var shallowCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
(2)ES6扩展运算符
var obj = { a:1, arr: [2,3] };
var obj1 = {...obj}
展开运算符使用的对象如果只是针对简单的一级基础数据,就是深拷贝;
展开运算符使用的对象内容包含二级或更多的复杂的数据,那就是浅拷贝
(3)数组方法(只适用于类数组对象)
Array.from(arrayLike)
从类数组对象或者可迭代对象中创建一个新的数组实例。返回一个新的数组。
var array1 = ['a', ['b', 'c'], 'd'];
var array2 = Array.from(array1);
array1[1][0] = 'e';
console.log(array2[1][0]);//输出结果为: "e"
Array.prototype.concat()
用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
var array1 = ['a', ['b', 'c'], 'd'];
var array2 = array1.concat();
array1[1][0] = 'e';
console.log(array2[1][0]);//输出结果为: "e"
Array.prototype.slice()
返回一个新的数组对象,这一对象是一个由 begin和 end(不包括end)决定的原数组的浅拷贝。原始数组不会被改变。
var array1 = ['a', ['b', 'c'], 'd'];
var array2 = array1.slice();
array1[1][0] = 'e';
console.log(array2[1][0]);//输出结果为: "e"
(4)ES6方法Object.assign()
用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。
它将返回目标对象。
var obj = { a:1, arr: [2,3] };
var obj1 = Object.assign({}, obj);
obj.arr[1] = 5;
console.log(obj1.arr[1]);//输出结果:5
通过JSON方法实现深拷贝
JSON的JSON.parse()和JSON.stringify()的两个方法实现。实现代码如下:
let arr = [1, 3, {
username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'xiaoming';
console.log(arr, arr4)