博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
lodash的cloneDeep
阅读量:6982 次
发布时间:2019-06-27

本文共 3459 字,大约阅读时间需要 11 分钟。

cloneDeep

上一篇说了clone,现在说一下跟深拷贝相关的cloneDeep方法。

function clone(value) {  return baseClone(value, false, true);}
function cloneDeep(value) {  return baseClone(value, true, true);}

arrayEach中,再次用到了baseClone,已经不适合再去简化相关逻辑了。我们删除掉浅拷贝的部分。

调用如下

cloneDeep([{a:1,b:2},3,4])

执行到了baseClone这里后,

function baseClone(value=[{a:1,b:2},3,4], isDeep=true, isFull=true, customizer, key, object, stack) {  var result;   if (result !== undefined) {    return result;  }  if (!isObject(value)) {    return value;  }  var isArr = isArray(value);  if (isArr) {   //初始化走这里 result为长度为3的空数组    result = initCloneArray(value);     } else {    var tag = getTag(value),        isFunc = tag == funcTag || tag == genTag;      if (tag == objectTag || tag == argsTag || (isFunc && !object)) {      if (isHostObject(value)) {        return object ? value : {};      }      result = initCloneObject(isFunc ? {} : value);        }    } else {      if (!cloneableTags[tag]) {        return object ? value : {};      }      result = initCloneByTag(value, tag, baseClone, isDeep);    }  }  // Check for circular references and return its corresponding clone.  stack || (stack = new Stack);  var stacked = stack.get(value);  if (stacked) {    return stacked;  }  stack.set(value, result);// 这里存入stack  if (!isArr) {    var props = isFull ? getAllKeys(value) : keys(value);  }  // 第一次props 为undefined,value=[{a:1,b:2},3,4]  arrayEach(props || value, function(subValue, key) {    if (props) {      key = subValue;      subValue = value[key];    }       // Recursively populate clone (susceptible to call stack limits). 递归克隆    //-1: subvalue => {a:1,b:2}, key => 0    // -2 subvalue => 3, key => 1    // -3 subvalue => 4, key => 2    assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));  });  return result;}

arrayEach

//-1: subvalue => {a:1,b:2}, key => 0assignValue([undefined,undefined,undefined],0,baseClone({a:1,b:2},true,true,undefined,0,[{a:1,b:2},3,4],stack))

-1中,执行了baseClone({a:1,b:2},true,true,undefined,0,[{a:1,b:2},3,4],stack))

当然,这一步也会走到对应的arrayEach中。

// value=> {a:1,b:2},result={}, if (!isArr) {    var props = isFull ? getAllKeys(value) : keys(value);  }  // props => ['a','b']  arrayEach(props || value, function(subValue, key) {    if (props) {      key = subValue; // key=a,subValue=1      subValue = value[key]; // key=b,subValue=2    }        assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));  });

执行到assignValue这里,

assignValue({},'a',baseClone(1,true,true,....) = 1)assignValue({a:1},'b',baseClone(2,true,true,...)=2)

此时result为{a:1,b:2}

当然你会想,如果{a:1,b:2, c:{name:"10"}}

也就是程序继续执行

assignValue({a:1,b:2},'c',baseClone({name:"10"},true,true,...) )

baseClone({name:"10"},true,true,...)

  • 它会初始化一个{}
  • 因为是对象,props是存在的,key就是name,subValue就是10.

程序会继续执行

//-1: subvalue => {a:1,b:2}, key => 0assignValue([undefined,undefined,undefined],0,baseClone({a:1,b:2},true,true,undefined,0,[{a:1,b:2},3,4],stack))// -2 subvalue => 3, key => 1assignValue([{a:1,b:2},undefined,undefined],1,baseClone(3,true,true,undefined,1,[{a:1,b:2},3,4],stack))// -3 subvalue => 4, key => 2 assignValue([{a:1,b:2},3,undefined],2,baseClone(4,true,true,undefined,2,[{a:1,b:2},3,4],stack))

返回最终的result。

总结

cloneDeep是需要递归拷贝的。我们可以总结下cloneDeep

  • 如果需要被clone的是number,string等类型,直接返回值
  • 如果是数组,首先会initClone出一个相同长度的空数组。
  • 如果是对象,首先会initClone一个空对象。原型链上的除外。

对于数组或者对象中的属性,又会进行一个递归判断,如果该属性(数组便是index)的value是一个number,string,执行结束,交出执行权。如果是数组或者对象,又会继续执行递归。

转载地址:http://ootpl.baihongyu.com/

你可能感兴趣的文章
台积电要造第一款7nm芯片 明年下半年可投产
查看>>
《逻辑与计算机设计基础(原书第5版)》——3.9 二进制加法器
查看>>
《中国人工智能学会通讯》——8.25 基于演化优化的生物网络配准
查看>>
飞鹤乳业CIO:移动化让企业品牌和消费者紧密连接
查看>>
教你编写Node.js中间件,实现服务端缓存
查看>>
美国税局再遭攻击:原是偷来的社会安全号码作祟
查看>>
2020年全球云服务规模将达3900亿美元
查看>>
Facebook、Netflix 等多家科技巨头谈“设计”
查看>>
雅虎核心业务售与Verizon:互联网先驱的时代终结
查看>>
市场规模占全国4成,广东物联网市场发展强劲
查看>>
ICS—CERT官网公示匡恩网络新发现四工控漏洞
查看>>
英国电价与光伏容量占比关系分析
查看>>
浅谈对5G核心网演进方向的几点展望
查看>>
明智地选择数据中心的五个注意事项
查看>>
开启物联网的真正潜力需要在更大程度上克服数据挑战
查看>>
张小龙公布微信小程序进展 可直接从桌面进入
查看>>
手机芯片三国杀:高通、联发科、展讯都想成霸主
查看>>
六大技巧提升员工信息安全意识
查看>>
保利协鑫多晶硅产量再创历史记录
查看>>
爱屋及乌 年轻投资者因喜爱Snapchat亏钱也买Snap股票
查看>>