搜索JavaScript對象的深度拷貝,每每會冒出JSON轉換和遞歸拷貝大法。但遇到大數據量,它們都有調用棧爆棧的風險
今天,咱們嘗試利用樹的利用深度/廣度優先遍從來實現對象的深度拷貝。如下代碼在chrome環境下所有測試經過。chrome
深度優先遍歷對象,利用棧作中間節點緩存緩存
function deepCopy(orginObject) { if (orginObject == null || typeof orginObject !== 'object') { return; } console.log('starting') const resultObject = {} const rootKey = Symbol('root'); //深度遍歷須要建立棧 const stack = []; for (let key of Object.keys(orginObject)) { stack.push({ key: key,//屬性名 value: orginObject[key],//value屬性記錄當前節點下屬數據 parent: resultObject//記錄節點在resultObject中的位置 }) } while (stack.length) { const currentNode = stack.pop(); const parent = currentNode.parent; const currentKey = currentNode.key; const currentValue = currentNode.value; //如果無下屬對象,返回其值 if (currentValue == null || typeof currentValue !== 'object') { parent[currentKey] = currentValue; } else { //若下屬值是對象,將子節點壓入棧中 parent[currentKey] = Object.prototype.toString.call(currentValue) === '[object Array]'?[]:{}; for (let key of Object.keys(currentValue)) { console.log('loop:' + key, currentValue[key]) stack.push({ key: key, value: currentValue[key], parent: parent[currentKey] }) } } } return resultObject; } var copyObj = deepCopy({ a: { b: 1, d: { e: 6 } }, c: 3 }); console.log(copyObj);
廣度優先遍歷對象,利用隊列作中間節點緩存oop
function deepCopy(orginObject) { if (orginObject == null || typeof orginObject !== 'object') { return; } console.log('starting') const resultObject = {} const rootKey = Symbol('root'); //深度遍歷須要建立棧 const queue = []; for (let key of Object.keys(orginObject)) { queue.push({ key: key,//屬性名 value: orginObject[key],//value屬性記錄當前節點下屬數據 parent: resultObject//記錄節點在resultObject中的位置 }) } while (queue.length) { const currentNode = queue.shift(); const parent = currentNode.parent; const currentKey = currentNode.key; const currentValue = currentNode.value; //如果無下屬對象,返回其值 if (currentValue == null || typeof currentValue !== 'object') { parent[currentKey] = currentValue; } else { //若下屬值是對象,將子節點壓入棧中 parent[currentKey] = Object.prototype.toString.call(currentValue) === '[object Array]'?[]:{}; for (let key of Object.keys(currentValue)) { console.log('loop:' + key, currentValue[key]) queue.push({ key: key, value: currentValue[key], parent: parent[currentKey] }) } } } return resultObject; } var copyObj = deepCopy({ a: { b: 1, d: { e: 6 } }, c: 3 }); console.log(copyObj);