對於深拷貝,淺拷貝的概念很少說,概念能夠自行百度喲!這裏對深拷貝對象進行一些研究!數組
針對只有值的數據對象,下面一行代碼足以!函數
JSON.parse(JSON.stringify(obj))
function clone(source) { var target = {}; for(var i in source) { if (source.hasOwnProperty(i)) { if (typeof source[i] === 'object') { target[i] = clone(source[i]); // 注意這裏 } else { target[i] = source[i]; } } } return target; }
問題存在:code
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; }
問題存在:對象
可使用一個WeakMap結構存儲已經被拷貝的對象,每一次進行拷貝的時候就先向WeakMap查詢該對象是否已經被拷貝,若是已經被拷貝則取出該對象並返回,將deepCopy函數改形成以下:原型鏈
function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { if(hash.has(obj)) return hash.get(obj) let cloneObj = Array.isArray(obj) ? [] : {} hash.set(obj, cloneObj) for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj }
問題存在:get
const obj = { arr: [111, 222], obj: {key: '對象'}, a: () => {console.log('函數')}, date: new Date(), reg: /正則/ig} function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null } function deepCopy(obj, hash = new WeakMap()) { let cloneObj; let Constructor = obj.constructor; switch(Constructor){ case RegExp: cloneObj = new Constructor(obj) break; case Date: cloneObj = new Constructor(obj.getTime()) break; case Function: cloneObj = eval(obj.toString()); break; default: if(hash.has(obj)) return hash.get(obj) cloneObj = new Constructor() hash.set(obj, cloneObj) } for (let key in obj) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } return cloneObj; } const cloneObj = deepCopy(obj); console.log(cloneObj);
更多遺留問題,針對函數進行拷貝,如果function,非箭頭函數,如何解決?還有,若要拷貝原型鏈上的屬性?如何拷貝不可枚舉屬性? 如何拷貝Error對象等等的坑?原型