You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

重构代码时出现Cannot read property 'push' of undefined问题(续)

嘿,我来帮你拆解这段代码背后的逻辑,你遇到的现象其实是JavaScript里对象引用特性短路赋值语法共同作用的结果,咱们一步步来理清楚:

核心代码的逻辑拆解

先看你这段关键代码:

link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});

这行代码用了JavaScript的||短路求值特性,工作流程是这样的:

  1. 先判断左侧表达式 nodes[link.source] 是否为「真值」(比如存在的对象、非空字符串等)
  2. 如果左侧是「假值」(比如undefined,说明nodes里还没有link.source这个键),就会执行右侧括号里的代码:nodes[link.source] = {name: link.source}
  3. 右侧的赋值语句会返回被赋值的对象(也就是{name: "Baratheon"}),然后把这个对象赋值给link.source

因为linklinks数组里的对象元素,JavaScript中对象属于「引用类型」——你操作link的时候,不是在操作一个拷贝,而是直接操作原数组里的那个对象本身。

举个具体例子:

  • 初始时link{source: "Baratheon", target: "Lannister"}link.source是字符串
  • 执行赋值后,你直接把link.source这个属性的值从字符串替换成了新创建的对象,所以原links数组里的那个对象的source属性自然就变了

为什么不执行赋值nodes也有对应值?

这大概率是因为你之前已经执行过这段代码,或者其他逻辑已经给nodes添加了对应的键值对:

  • 第一次执行时,nodes[link.source]不存在,所以会执行右侧的赋值,把对象存入nodes
  • 之后再执行这段代码时,左侧的nodes[link.source]已经是存在的对象(真值),||会直接返回这个对象,不会再执行右侧的赋值,但nodes里已经有之前存入的值了

总结一下这段代码的作用

它本质上是在做一个「映射替换」:把links数组中每个linksource(原本是字符串ID),替换成nodes中对应的对象;如果nodes里没有这个对象,就先创建一个并存入nodes,再替换link.source

内容的提问来源于stack exchange,提问作者specialscene

火山引擎 最新活动