Last active
June 16, 2018 12:57
-
-
Save yantze/c428dd022c0c85db2d14c37da4c1dec0 to your computer and use it in GitHub Desktop.
deep copy a object
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* https://gist.github.com/yantze/c428dd022c0c85db2d14c37da4c1dec0 | |
* https://github.com/pvorb/clone/blob/master/clone.js#L74:8 | |
* author: yantze | |
* typeoof | |
* 对象为 function ,可能是 Function, class, Symbol, 不复制,因为这些是非结构化对象,但可以生成实例 | |
* 对象为 object, 可能是 Date 实例, class 实例,{}, [], Regex 实例, Buffer 实例, 错误实例 | |
*/ | |
function deepCopy(obj) { | |
let map = new WeakMap() | |
function __objToStr(o) { | |
return Object.prototype.toString(o) | |
} | |
function _clone(obj) { | |
if (obj === null || obj === undefined || typeof obj === 'function') { | |
return obj | |
} | |
let existobj = map.get(obj) | |
//如果这个对象已经被记录则直接返回 | |
if(existobj) { | |
return existobj | |
} | |
let child | |
let proto | |
if (typeof obj === 'object' && Array.isArray(obj)) { | |
child = [] | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object RegExp]') { | |
child = new RegExp(obj.source) // 缺少 flags | |
return child | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object Date]') { | |
child = new Date(obj) | |
return child | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object Number]') { | |
child = new Number(obj) | |
return child | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object Boolean]') { | |
child = new Boolean(obj) | |
return child | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object String]') { | |
child = new String(obj) | |
return child | |
} | |
if (typeof obj === 'object' && __objToStr(obj) === '[object Symbol]') { | |
child = new Symbol(obj) | |
return child | |
} | |
if (typeof obj === 'object' && typeof Buffer !== 'undefined' && Buffer.isBuffer(a)) { // nodejs | |
child = new Buffer(obj) | |
return child | |
} | |
if (typeof obj === 'string') { | |
return obj | |
} | |
if (typeof obj === 'number') { | |
return obj | |
} | |
// Uint8Array, Uint16Array, Uint32Array, BufferArray | |
if (child === undefined) { | |
proto = Object.getPrototypeOf(obj) | |
child = Object.create(proto) | |
} | |
map.set(obj, child) | |
for (let i in obj) { | |
// if (proto) { | |
// let attr = Object.getPrototypeOf(obj, i) | |
// if (attr && attr.set == null) continue | |
// } | |
child[i] = _clone(obj[i]) | |
} | |
return child | |
} | |
return _clone(obj) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment