重构代码时无法读取未定义的属性“push”

2024-06-24

我想让这段代码变得更简单:

links.forEach(function(link) {
    link.source = nodes[link.source] ||
        (nodes[link.source] = {
            name: link.source
        });
    link.target = nodes[link.target] ||
        (nodes[link.target] = {
            name: link.target
        });
    console.log(nodes)
});

所以,我这样重构它:

links.forEach(function(link) {
    if (nodes[link.source] == null) {
        nodes[link.source] = {
            name: link.source
        };
    } else if (nodes[link.target] == null) {
        nodes[link.target] = {
            name: link.target
        };
    } else {
        console.log('Not problem');
    }
});

但是,现在我收到此错误:

无法读取未定义的属性“push”

这是完整的原始代码:

<DOCTYPE html>
<meta charset="utf-8">
<style>

 .node {
   fill: #4D00DD;
   stroke: #fff;
   stroke-width: 2px;
  }

 .link {
   stroke: #777;
   stroke-width: 8px;
  }

</style>
<body>
  <script src="https://d3js.org/d3.v3.min.js"></script>
<script>
    var width = 1080,
        height = 960;

    var links = [
      { source : "Baratheon", target : "Lannister"},
      { source : "Baratheon", target : "Stark"},
      { source : "Lannister", target : "Stark"},

    ];

    var nodes = {};

    // parse links to nodes

    links.forEach(function(link) {
      link.source = nodes[link.source] ||
        (nodes[link.source] = {name: link.source});
      link.target = nodes[link.target] ||
        (nodes[link.target] = {name: link.target});
      console.log(nodes)
    });

   // add svg to our body

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

    var force = d3.layout.force()
        .size([width, height])
        .nodes(d3.values(nodes))
        .links(links)
        .on("tick", tick)
        .linkDistance(600)
        .start();

    var link = svg.selectAll(".link")
        .data(links)
        .enter().append("line")
        .attr("class", "link")

    var node = svg.selectAll(".node")
        .data(force.nodes())
        .enter().append("circle")
        .attr("class", "node")
        .attr("r", width * 0.03);

    function tick(e) {

      node.attr("cx", function(d) { return d.x; })
          .attr("cy", function(d) { return d.y; })
          .call(force.drag);

      link.attr("x1", function(d) { return d.source.x; })
          .attr('y1', function(d) { return d.source.y; })
          .attr('x2', function(d) { return d.target.x; })
          .attr("y2", function(d) { return d.target.y; })
    }
</script>

您试图使该块更易于阅读,这是一个非常好的练习。然而,你忘记了一些事情。

在原始代码中,这个作业...

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

...以非常详细的方式意味着:

Does nodes[link.source]存在?如果是,请使link.source = nodes[link.source]。如果没有,则使nodes[link.source] = {name: link.source},然后使link.source = nodes[link.source].

但在你的if你从未设定过的逻辑link.source if nodes[link.source] exists!

另外,您不需要:

if (nodes[link.source] == null) {

一个简单的if (!nodes[link.source]) {将工作。

最后,放下那个else。第二if must进行评估,无论第一个结果如何if.

话虽如此,这应该是您重构的代码:

links.forEach(function(link) {
  if (!nodes[link.source]) {
    nodes[link.source] = {
      name: link.source
    }
  };
  //Look, Ma, no 'else' here!
  if (!nodes[link.target]) {
    nodes[link.target] = {
      name: link.target
    }
  };
  //add these lines:
  link.source = nodes[link.source];
  link.target = nodes[link.target];
});

这是正在运行的演示:

var width = 600,
  height = 300;

var links = [{
    source: "Baratheon",
    target: "Lannister"
  }, {
    source: "Baratheon",
    target: "Stark"
  }, {
    source: "Lannister",
    target: "Stark"
  },

];

var nodes = {};

links.forEach(function(link) {
  if (!nodes[link.source]) {
    nodes[link.source] = {
      name: link.source
    }
  };
  if (!nodes[link.target]) {
    nodes[link.target] = {
      name: link.target
    }
  };
  link.source = nodes[link.source];
  link.target = nodes[link.target];
});

// add svg to our body

var svg = d3.select("body").append("svg")
  .attr("width", width)
  .attr("height", height);

var force = d3.layout.force()
  .size([width, height])
  .nodes(d3.values(nodes))
  .links(links)
  .on("tick", tick)
  .linkDistance(50)
  .start();

var link = svg.selectAll(".link")
  .data(links)
  .enter().append("line")
  .attr("class", "link")

var node = svg.selectAll(".node")
  .data(force.nodes())
  .enter().append("circle")
  .attr("class", "node")
  .attr("r", width * 0.03);

function tick(e) {

  node.attr("cx", function(d) {
      return d.x;
    })
    .attr("cy", function(d) {
      return d.y;
    })
    .call(force.drag);

  link.attr("x1", function(d) {
      return d.source.x;
    })
    .attr('y1', function(d) {
      return d.source.y;
    })
    .attr('x2', function(d) {
      return d.target.x;
    })
    .attr("y2", function(d) {
      return d.target.y;
    })
}
<script src="https://d3js.org/d3.v3.min.js"></script>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

重构代码时无法读取未定义的属性“push” 的相关文章

  • JavaScript 中的 touchstart 不再返回 TouchList

    我遇到了一个非常奇怪的问题 我正在绑定touchstart事件到一个元素 并且想要检索事件的 X 和 Y 坐标 全部文档 http developer apple com library safari documentation apple
  • 使用 ReactJS 旋转图像预览

    我正在尝试使用 ReactJS 旋转图像的预览 因此 我首先允许渲染预览的上传功能 然后在用户点击上传之前 我希望他们可以选择根据自己的喜好旋转图像 这是我用来预览图像的 class ImageUpload extends React Co
  • 工厂函数方法不更新变量

    我正在尝试设置一个工厂函数 该函数将更新所述工厂函数中特定变量的值 这看起来实现起来很简单 但是 每当我测试它时 我都会得到变量的原始设置值 而不是更新后的值 我确信在范围界定方面我缺少一些细微差别 但这里到底发生了什么 const fac
  • 请使用同一按钮播放和暂停音频

    我有这段代码并且只是播放 但我想使用相同的按钮 图像 播放和暂停 并且我不知道我需要添加什么 我需要做什么 请帮帮我
  • JavaScript:所有标准内置对象实际上都是构造函数吗?

    我最近一直在研究 JavaScript 在花了几个月的时间之后 我仍然对一些内部结构感到困惑 具体来说 我试图理解所谓的标准内置对象 https developer mozilla org en US docs Web JavaScript
  • EXT JS中有全局变量吗

    在 java 和 C 中 我们可以全局存储变量并从项目中的任何位置访问它的值 比如说 我在一个名为Residence我正在保存residenceNumber这是一个INT到一个名为的全局变量houseNumberGlobalVariable
  • Karma Webpack - 错误:找不到模块“./test/utilities.js”

    我正在使用 Karma Webpack 进行项目的单元测试 当我跑步时karma start 我有这个错误 Error Cannot find module test utilities js at myproject test campa
  • 将 Babel 与单个输出文件和 ES6 模块一起使用

    这是我的 gulp 任务 将 ES6 代码编译成单个 ES5 文件 我使用类和模块 import export 在 ES6 中 gulp src paths scripts pipe sourcemaps init pipe babel p
  • 绑定到以缩放行为结束的缩放

    如果有一种方法可以在缩放行为转换结束时轻松绑定到事件 当用户松开鼠标或触摸移动图表的某些内容时 那将会很方便 是否可以通过绑定所有 up 事件来实现这一点 或者这是人们通过其他方式完成的事情 在 d3 v4 中 zoom on 类型名称已更
  • JSON 解析错误 - JSON 中位置 1 处出现意外标记 o

    我需要获取一个 JSON 对象并记录标题控制台以实现自动完成功能 我的 json 的示例如下 title Example 1 url http www example1 com title Example 2 url http www ex
  • 递归process.nextTick警告

    作为我的应用程序的一部分 我有以下代码行 process nextTick function pre populate cache with all users console log scanning users table in ord
  • Google 闭包编译器使用 WebStorm

    我喜欢用谷歌闭包编译器 https developers google com closure compiler in WebStorm https www jetbrains com webstorm 我已经通过 npm 下载了它 npm
  • pointdown 与 onclick:有什么区别?

    两者有什么区别onpointerdown and onclick事件处理程序 有任何实际差异吗 事件在 DOM 树上传播的方式不一样吗 是否有一些设备仅响应这些事件之一 我最初以为这只是pointerdown在触摸设备或笔中触发 但是onc
  • 如何在Javascript中保存zip文件的二进制数据?

    我从 AJAX 响应中收到以下响应 这是 zip 文件的响应 请让我知道如何在 Javascript 中保存此 filename zip ZIP 里面有 PDF 文件 我的代码是这样的 ajax url baseURLDownload se
  • Backbone.View:delegateEvents 未将事件重新绑定到子视图

    我已将这个问题分解为尽可能小的示例 即 它只是为了演示问题 不一定代表现实世界的场景 假设我有一个父视图 此处为 MainView 其中包含一个子视图 此处为 SubView 如果在任何时候我需要重新渲染父视图 从而重新渲染子视图 我就会丢
  • 使用预先存在的数据库创建 PhoneGap iOS 应用程序

    我最近开始开发一个使用 PhoneGap 版本 2 8 0 作为药物查找器的应用程序 过去 我创建了该工具的 Web 版本 它使用 jQuery Mobile 和 PHP 来访问远程 SQL 数据库 PhoneGap 似乎是一个很有吸引力的
  • jQuery 分钟和秒倒计时器

    我想创建一个 jquery 倒计时器 我尝试了以下代码 但它不起作用 我该怎么办 DEMO https jsfiddle net tbosn210 https jsfiddle net tbosn210 var interval setIn
  • Javascript 或 Coffeescript 中的“Bucket Fill”算法

    我正在编写一个小coffeescript js应用程序 允许用户设计图标 16x16像素或32X32像素 该图标实际上是一个带有颜色单元的二维数组 单元格可以有颜色或为空 我希望用户能够使用 桶油漆 工具填充空白单元格 代表着 如果用户单击
  • 如何捕获 google 地图的无效 API 密钥

    我有这个代码 如果密钥无效 则会弹出警报 但我想在这种情况下执行一些操作 但我不知道如何连接它 有任何想法吗 Google 不提供检查 Google 地图 API 密钥的外部方法 因此 您无法使用例如查询某些服务 此代码有效吗abcde12
  • JQuery 循环遍历动态元素并获取数据值

    我正在尝试使用可折叠面板来完成我的要求 sport on click function var thisId this attr id var thisChildren this sportlist thisChildren each fu

随机推荐