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
递归的好是很有意思的,比如第一个例子比第二个例子的写法巧妙,虽然简单,但很好玩味。