js代码:
// 浅拷贝封装的函数
function copy1(obj){
let obj3 = {}
for(let k in obj){
obj3[k] = obj[k] // 浅拷贝,拷贝的是对象属性的引用,而并不是对象本身。
}
return obj3
}
// 深拷贝封装的函数(递归的思想)
function copy2(obj){
let obj2 = {}
for(let k in obj){
obj2[k] = typeof obj[k] === "object" ? copy2(obj[k]) : obj[k] // 深拷贝,把一个对象的属性复制给另一个对象
}
return obj2
}
/* 1.浅拷贝 */
let ff = {car: {brand: "奔驰"}, money: 1000000} // 源数据
let ffNew = copy1(ff) // 拷贝的数据
console.log('浅拷贝与源数据对比:',ff==ffNew) // 把下面的改值注释之后比较,打印结果为false
/* 浅拷贝改值 */
ffNew.money = '改了外层值' // 修改第一层属性值,不会影响到源数据
ffNew.car.brand = '改浅拷贝改了内层值' // 修改内层对象的属性值,会影响到源数据
console.log('源数据ff:',ff)
console.log('浅拷贝出来的ffNew:',ffNew)
console.log('--------------------------------------------------------------------------')
/* 2.深拷贝 */
let jj = {car: {brand: "奔驰"}, money: 1000000}
let jjNew = copy2(jj)
console.log('浅拷贝与源数据对比:',jj==jjNew) // 把下面的改值注释之后比较,打印结果为false
/* 深拷贝改值 */
jjNew.money = '改了外层值'
jjNew.car.brand = '深拷贝改了内层值' // 修改内外层对象的属性值均不会影响到源数据
console.log('源数据jj:',jj)
console.log('深拷贝jjNew:',jjNew)
console.log('--------------------------------------------------------------------------')
/* 3.深拷贝与浅拷贝比较 */
let cc = {car: {brand: "奔驰"}, money: 1000000}
let ccQ = copy1(cc)
let ccS = copy2(cc)
console.log('深浅拷贝出来的值对比:',ccQ == ccS) // 输出为 false
console.log('--------------------------------------------------------------------------')
/* 4.源数据直接赋值*/
let zz = {car: {brand: "奔驰"}, money: 1000000}
let zzNew = zz
console.log('直接赋值对比:', zzNew == zz) // 输出为true
控制台输出结果:
总结
【相同点】
深拷贝,浅拷贝:拷贝出来的内容与源对象相同。深浅拷贝出来的对象与源对象三者进行对比,输出均为false,即实质不是 一个同一对象;
【不同点】
1.浅拷贝:只能拷贝对象的第一层(即简单数据);对于对象包含对象的对象,拷贝的是对象属性的
引用而并不是对象本身,修改内层对象的数据会影响源数据。
2.深拷贝:修改新对象的任何值都不会影响到源对象,所以复杂类型的数据要用深拷贝。
3.直接赋值:可以理解为俩对象地址完全相同,即同一个对象;修改新对像任意属性值都会影响源数据。
【拓展知识】
【递归】copy2函数内部自己调用copy2函数本身,即为递归。
【注意】
递归函数一定要有递归结束的条件,否则会进入死循环。这里结束递归的条件是 typeof obj[k] != “object”
用递归求和
// 目的: 用递归计算 1 - 4的和
function sum(n) {
if (n == 1) { return 1; }
return sum(n - 1) + n;
}
var result = sum(4);
console.log(result);