js-读书笔记-函数式编程-递归-深度克隆实现

import _ from 'underScore'
import Utils from '../lib/utils.js'
// 递归和组合函数 conjoin Disjoin
// 深克隆 deepClone 的实现

// 递归克隆(深克隆)
// function deepClone(obj) {
//   if(!Utils.existy(obj) || !_.isObject(obj)) {
//     return obj
//   }
//   let temp = new obj.constructor() // 生成[] 或者 {}。
//   for(let key in obj) {
//     if(obj.hasOwnProperty(key)) {
//       // 不管是不是对象,都调用,函数前面有非对象的拦截,非对象会被直接返回,对象会继续循环。
//       temp[key] = deepClone(obj[key])
//     }
//   }
//   return temp
// }

// let x = [{a: [1,2,3], b: 42}, {c: {d: []}}]
// let y = deepClone(x)
// console.log('y', y)
// y[0].b = 1
// console.log('x', x)
// console.log('y', y)

// 另一个写法,个人觉得上面的写法更巧妙。
// function deepClone2(obj) {
//   if(!obj && typeof obj !== 'object') {
//     return new Error('error arguments', 'shallowClone')
//   }
//   let temp = new obj.constructor()
//   for(let key in obj) {
//     if(obj.hasOwnProperty(key)) { 
//       temp[key] = typeof obj[key] === 'object' ? deepClone2(obj[key]) : obj[key]
//     }
//   }
//   return temp
// }

// let n = [{a: [1,2,3], b: 42}, {c: {d: []}}]
// let m = deepClone2(n)
// console.log('m', m)
// m[0].b = 1
// console.log('n', n)
// console.log('m', m)

/* 
y [ { a: [ 1, 2, 3 ], b: 42 }, { c: { d: [] } } ]
x [ { a: [ 1, 2, 3 ], b: 42 }, { c: { d: [] } } ]
y [ { a: [ 1, 2, 3 ], b: 1 }, { c: { d: [] } } ]
*/

// 深克隆+symbol
// function deepCloneSymbol(obj) {
//   if(!Utils.existy(obj) || !_.isObject(obj)) {
//     return obj
//   }
//   let temp = new obj.constructor() // 生成[] 或者 {}
//   for(let key of Reflect.ownKeys(obj)) { // symbol需要Reflect.ownKeys才能获取到。
//     if(obj.hasOwnProperty(key)) {
//       temp[key] = deepCloneSymbol(obj[key])
//     }
//   }
//   return temp
// }

// let a = [{a: 1, b: [2]}, {[Symbol.for('c')]: 3}]
// let b = deepCloneSymbol(a)
// console.log('a', a)
// console.log('b', b)
// b[1][Symbol.for('c')] = 4
// b[0].a = 11
// console.log('a', a)
// console.log('b', b)

// let a = [{a: [1,2,3], b: 42}, {c: {d: []}, [Symbol.for('a')]: 111}]
// let b = deepCloneSymbol(a)
// console.log('b', b)
// console.log('a', a)
// b[1][Symbol.for('a')] = 222
// console.log('b', b)

/* 
b [ { a: [ 1, 2, 3 ], b: 42 }, { c: { d: [] }, [Symbol(a)]: 111 } ]
a [ { a: [ 1, 2, 3 ], b: 42 }, { c: { d: [] }, [Symbol(a)]: 111 } ]
b [ { a: [ 1, 2, 3 ], b: 42 }, { c: { d: [] }, [Symbol(a)]: 222 } ]
*/

// 深拷贝+Symbol+function,去除函数限制,函数也拷贝。
function deepClone(obj) {
	if(!(obj != null && obj != false) || !(typeof obj === 'object')) {
		return obj
	}
	let newObj = new obj.constructor()
	for(let k of Reflect.ownKeys(obj)) {
		if(obj.hasOwnProperty(k)) {
			newObj[k] = deepClone(obj[k])
		}
	}
	return newObj
}
let a = [{a: 1, b: [2]}, {[Symbol.for('c')]: 3}, {d: function(){console.log(4)}}]
let b = deepClone(a)
console.log('a', a) // a [ { a: 1, b: [ 2 ] }, { [Symbol(c)]: 3 }, { d: [Function: d] } ]
console.log('b', b) // a [ { a: 1, b: [ 2 ] }, { [Symbol(c)]: 3 }, { d: [Function: d] } ]
b[1][Symbol.for('c')] = 4
b[0].a = 11
console.log('a', a) // a [ { a: 1, b: [ 2 ] }, { [Symbol(c)]: 3 }, { d: [Function: d] } ]
console.log('b', b) // b [ { a: 11, b: [ 2 ] }, { [Symbol(c)]: 4 }, { d: [Function: d] } ]
b[2].d() // 4
a[2].d = function() {console.log(5)}
b[2].d() // 4
a[2].d() // 5

递归的好是很有意思的,比如第一个例子比第二个例子的写法巧妙,虽然简单,但很好玩味。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值