审核中~
溜忙之道
首页
溜忙手册
offer之道
项目Git
写文章
登录
·
注册
登录
没有账号,去注册
注册
已有账号,去登录
博客
深拷贝
南易_站长
阅读量:12416
关注
深拷贝
## 普通拷贝 ``` function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj) { let tempObj = Array.isArray(obj) ? [] : {} for(let key in obj) { tempObj[key] = isObj(obj[key]) ? deepCopy(obj[key]) : obj[key] } return tempObj } ``` ## 优化版 ``` /** * Checks if `value` is the `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * isObject({}) * // => true * * isObject([1, 2, 3]) * // => true * * isObject(Function) * // => true * * isObject(null) * // => false */ function isObject(value) { const type = typeof value return value != null && (type == 'object' || type == 'function') } /** * @desc 深拷贝,结构化拷贝,支持string,number,date,reg等格式,不支持function拷贝 * @param {Any} obj * @param {WeakMap} hash * @return {Any} */ function deepClone(obj, hash = new WeakMap()) { if (null == obj || "object" != typeof obj) return obj; let cloneObj let Constructor = obj.constructor console.log(1, Constructor) switch (Constructor) { case RegExp: cloneObj = new Constructor(obj) break case Date: cloneObj = new Constructor(obj.getTime()) break default: if (hash.has(obj)) return hash.get(obj) cloneObj = new Constructor() hash.set(obj, cloneObj) console.log(2, hash.get(obj)) } for (let key in obj) { console.log(3, key, cloneObj) cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key], hash) : obj[key]; console.log(4, key, cloneObj[key]) } return cloneObj } ``` ## 面试版 ``` /** * deep clone * @param {[type]} parent object 需要进行克隆的对象 * @return {[type]} 深克隆后的对象 */ const clone = parent => { // 判断类型 const isType = (obj, type) => { if (typeof obj !== "object") return false; const typeString = Object.prototype.toString.call(obj); let flag; switch (type) { case "Array": flag = typeString === "[object Array]"; break; case "Date": flag = typeString === "[object Date]"; break; case "RegExp": flag = typeString === "[object RegExp]"; break; default: flag = false; } return flag; }; // 处理正则 const getRegExp = re => { var flags = ""; if (re.global) flags += "g"; if (re.ignoreCase) flags += "i"; if (re.multiline) flags += "m"; return flags; }; // 维护两个储存循环引用的数组 const parents = []; const children = []; const _clone = parent => { if (parent === null) return null; if (typeof parent !== "object") return parent; let child, proto; if (isType(parent, "Array")) { // 对数组做特殊处理 child = []; } else if (isType(parent, "RegExp")) { // 对正则对象做特殊处理 child = new RegExp(parent.source, getRegExp(parent)); if (parent.lastIndex) child.lastIndex = parent.lastIndex; } else if (isType(parent, "Date")) { // 对Date对象做特殊处理 child = new Date(parent.getTime()); } else { // 处理对象原型 proto = Object.getPrototypeOf(parent); // 利用Object.create切断原型链 child = Object.create(proto); } // 处理循环引用 const index = parents.indexOf(parent); if (index != -1) { // 如果父数组存在本对象,说明之前已经被引用过,直接返回此对象 return children[index]; } parents.push(parent); children.push(child); for (let i in parent) { // 递归 child[i] = _clone(parent[i]); } return child; }; return _clone(parent); }; ```
评论
表情
发送
8
评论