<script>
function toType(obj) {
return ({}).toString.call(obj).split(' ')[1].replace(']', '').toLowerCase()
}
function shallowClone(obj) {
let type = toType(obj),
Ctor = obj.constructor
if (/^(symbol|bigint)$/i.test(type)) {
return Object(obj)
}
if (/^(regexp|date)$/i.test(type)) {
return new Ctor(obj)
}
if (/^(error)$/i.test(type)) {
return new Ctor(obj.message)
}
if (/^function$/i.test(type)) {
return function () {
obj.call(this, ...arguments)
}
}
if (/^(object|array)$/i.test(type)) {
let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)]
var result = new Ctor()
keys.forEach(i => {
result[i] = obj[i]
})
return result
}
return obj
}
function deepClone(obj, cache = []) {
if (!/^(object|array)$/i.test(toType(obj))) {
return shallowClone(obj)
}
if (!cache.includes(obj)) {
cache.push(obj)
} else {
return obj
}
let Ctor = obj.constructor,
result = new Ctor(),
keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)]
keys.forEach(i => {
result[i] = deepClone(obj[i], cache)
})
return result
}
var obj = {
0: 'math',
1: 'chinese',
2: 'elglish',
score: {
math: 98,
chinese: 100,
elglish: 19,
},
reg: /\d+/,
time: new Date,
friends: ['tom', 'jerry'],
say: function () {
console.log('good good study!');
},
tag: Symbol('TAG'),
[Symbol.toStringTag]: 'object'
};
obj.xxx = obj
var obj1 = deepClone(obj)
</script>