【问题标题】:D3 javascript Difference between foreach and eachD3 javascript foreach 和 each 的区别
【发布时间】:2012-11-08 01:59:27
【问题描述】:

D3js 中forEacheach 有什么区别?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    首先,.forEach() 不是 d3 的一部分,它是 javascript 数组的原生函数。所以,

    ["a", "b", "c"].forEach(function(d, i) { console.log(d + " " + i); });
    // Outputs:
    a 0
    b 1
    c 2
    

    即使页面上没有加载 d3,它也可以工作。

    接下来,d3 的.each() 适用于 d3 选择(当您使用d3.selectAll(...) 时会得到什么)。从技术上讲,您可以在 d3 选择上调用 .forEach(),因为在幕后,d3 选择是一个具有额外功能的数组(其中一个是 .each())。但你不应该这样做,因为:

    1. 这样做不会产生所需的行为。要知道如何将.forEach() 与 d3 选择一起使用以产生任何所需的行为,需要深入了解 d3 的内部工作原理。那么为什么要这样做,如果您可以使用 API 的文档化、公开部分。

    2. 1234563与d 关联的元素。换句话说,来自function(d,i) {} 内部的console.log(this) 将记录类似<div class="foo"></div> 或任何html 元素的内容。这很有用,因为你可以在这个this 对象上调用函数来更改它的CSS 属性、内容或其他任何东西。通常,您使用 d3 来设置这些属性,如 d3.select(this).style('color', '#c33');

    主要的收获是,使用.each(),您可以访问您需要的3 个东西:dthisi。使用.forEach(),在一个数组上(就像一开始的例子一样)你只能得到两件事(di),你必须做很多工作才能将 HTML 元素与这两件事。这就是 d3 的用处。

    【讨论】:

    • 感谢您写了一个很棒的答案,并且没有包括任何在 SO 上很常见的不必要的 snark...
    • 这里应该有一个警告:当您确实需要为 'this' 关键字设置不同的范围,但在调用的函数中不需要数据时, selection[0].forEach(...) 是比 selection.each 方便得多,如果 'this' 在仅引用 DOM 元素之外有意义,则需要在父函数中使用 'self = this' 解决方法。
    • @sdupton 对this 的作用域是许多 d3 场景中的一个问题,在这些场景中,您传递高阶函数,包括例如 selection.style("color", function(d,i) { /* here 'this' is a DOM element */ })。我相信这就是为什么 d3 类(例如 d3.svg.axis)不使用 prototype 定义类的方法的部分原因——作为避免依赖 this 的一种方式。但我看不出selection[0].forEach(...) 是如何避免这个问题的。是不是同样的问题?
    • @meetamit 您可以使用第二个参数显式限定“this”以在 Array.prototype.forEach 中使用,该参数在要在每个元素上调用的函数之后传递。当您编写任何类似于面向对象的包装器(我使用的是 ES6 类)时,失去“this”的显式范围可能会很糟糕。
    • @sdupton,很酷——我不知道.forEach 接受了第二个参数来确定this 的范围。它让我意识到你可以使用类似的东西来实现与 d3 的 .each() 相同的效果,方法是使用 javascript 的 .bind() 方法。例如,以下内容将this 限定为window 并将console.log 它:selection.each(function() { console.log(this); }.bind(window))
    猜你喜欢
    • 2016-06-11
    • 2012-11-29
    • 2016-07-20
    • 2013-03-28
    • 2013-08-06
    • 2016-03-29
    • 1970-01-01
    相关资源
    最近更新 更多