注:深浅拷贝的区别只适用于array【数组】与object【对象】
浅拷贝:相当于使两个数组指针指向相同的地址,任一个数组元素发生改变,影响另一个。
深拷贝:两数组指针指向不同的地址,数组元素发生改变时不会相互影响。
var a = [1, 2, 3]
b = a
console.log("a: ",a)
console.log("b: ",b)
b[0] = 99;
console.log("---- after changed array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
方法一:JavaScript的slice函数
var a = [1, 2, 3]
b = a.slice(0)
console.log("a: ",a)
console.log("b: ",b)
b[0] = 99;
console.log("---- after changed deepClone array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
方法二、JavaScript的concat函数
var a = [1, 2, 3]
b = a.concat([])
console.log("a: ",a)
console.log("b: ",b)
b[0] = 99;
console.log("---- after changed deepClone array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
方法三、jquery的extend函数
1、一维数组
var a = [1, 2, 3]
// jQuery.extend([deep], target, object1, object2, object3...),
// [deep]:默认false【不能显式设置为false;值为true时深度合并对象。
// target:其他对象复制到该对象
// object:被合并的对象
b = $.extend(true, [], a)
console.log("a: ",a)
console.log("b: ",b)
b[0] = 99;
console.log("---- after changed deepClone array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
运行结果:此例中【deep】值为true和false时结果相同
2、二维数组
1、【deep】值为false,对象不进行深度合并
var a = [[1, 2, 3], 4, [5, 6]]
b = $.extend([], a)
console.log("a: ",a)
console.log("b: ",b)
b[0][0] = 99;
console.log("---- after changed deepClone array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
2、【deep】值为true,对象进行深度合并
var a = [[1, 2, 3], 4, [5, 6] ]
b = $.extend(true, [], a)
console.log("a: ",a)
console.log("b: ",b)
b[0][0] = 99;
console.log("---- after changed deepClone array b ----- ")
console.log("a: ",a)
console.log("b: ",b)
方法一、自定义函数
function shallowCopy(obj1, obj2) {
for( var key in obj1){
if (obj1.hasOwnProperty(key)) {
obj2[key] = obj1[key]
}
}
}
function showKeys(obj) {
for( var key in obj){
if (obj.hasOwnProperty(key)) {
console.log(key, ":", obj[key]);
}
}
}
var a = {
sing:true,
dance:{today:false, tommorrw:true}
}
b = {}
shallowCopy(a, b)
showKeys(a)
showKeys(b)
b.sing = false
b.dance.today = true
console.log("------------- after changed object b -------------- ")
showKeys(a)
showKeys(b)
运行结果:由于对象的浅拷贝只复制第一层属性,因此obj b第一层属性的改变不会影响复制源,而第二层属性仍指向同一块地址,因此obj b的dance属性的today属性作改变之后,同一块地址处的obj a的dance属性的today属性同时变化了。
方法二、jquery的extend函数:【deep】参数为false
function showKeys(obj) {
for( var key in obj){
if (obj.hasOwnProperty(key)) {
console.log(key, ":", obj[key]);
}
}
}
var a = {
sing:true,
dance:{today:false, tommorrw:true}
}
b = $.extend({}, a)
showKeys(a)
showKeys(b)
b.sing = false
b.dance.today = true
console.log("------------- after changed object b -------------- ")
showKeys(a)
showKeys(b)
方法:jquery的extend函数:【deep】参数为true
function showKeys(obj) {
for( var key in obj){
if (obj.hasOwnProperty(key)) {
console.log(key, ":", obj[key]);
}
}
}
var a = {
sing:true,
dance:{today:false, tommorrw:true}
}
b = $.extend(true, {}, a)
showKeys(a)
showKeys(b)
b.sing = false
b.dance.today = true
console.log("------------- after changed object b -------------- ")
showKeys(a)
showKeys(b)
实现对object、array、number、boolean、string的值进行复制,其中object和array需要判断,用各自的方法进行复制,其他数据类型可直接复制。
function cloneAll(obj) {
if (obj instanceof Array) {
var result = []
for (var i = 0, max = obj.length; i < max; i++) {
result[i] = cloneAll(obj[i])
}
return result
}
else if(obj instanceof Object){
var result = {}
for(key in obj){
result[key] = cloneAll(obj[key])
}
return result
}
else{
return obj
}
}