破解递归爆栈的深拷贝
破解递归爆栈的深拷贝
https://juejin.im/post/5c45112e6fb9a04a027aa8fe#heading-11
递归爆栈问题
https://blog.csdn.net/weixin_34151004/article/details/88452339
函数 caller 运行时,调用其他函数 called ,js会在调用栈中新开一个调用帧存储作用域和上下文信息,而caller的调用帧信息仍需要保存。而内存中调用栈存储信息有限,递归情况下,如果递归层次过深会导致调用栈耗光而引起stack overflow —— 爆栈。
----------------------------------------------------------
递归深拷贝
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; }
破解递归爆栈的深拷贝
function cloneDeep5(x) { const root = {}; // 栈 const loopList = [ { parent: root, key: undefined, data: x, } ]; while(loopList.length) { // 广度优先 const node = loopList.pop(); const parent = node.parent; const key = node.key; const data = node.data; // 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素 let res = parent; if (typeof key !== 'undefined') { res = parent[key] = {}; } for(let k in data) { // if (data.hasOwnProperty(k)) { // 改用call方法判断原因见后面 if(Object.prototype.hasOwnProperty.call(data, "b")) if (typeof data[k] === 'object') { // 下一次循环 loopList.push({ parent: res, key: k, data: data[k], }); } else { res[k] = data[k]; } } } } return root; } 作者:木易杨说 链接:https://juejin.im/post/5c45112e6fb9a04a027aa8fe 来源:掘金 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
data.hasOwnProperty(k) 改用
Object.prototype.hasOwnProperty.call(data, "b") 原因
var myObject = Object.create( null ); myObject.b = 2; ("b" in myObject); // true myObject.hasOwnProperty( "b" ); // TypeError: myObject.hasOwnProperty is not a function
测试 cloneDeep5
let param3 = Object.create(null); param3.a ='xa1'; param3.c = function(){ console.log(this.a); } let param4 = cloneDeep5(param3); console.log(param4);