D3映射函数,混淆了传入的多个函数

时间:2017-05-23 12:44:06

标签: javascript d3.js

迈克的这个例子

https://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172

以下一行让我感到困惑,我想知道是否有人可以清理它。

x.domain(s.map(x2.invert, x2));

为什么x2作为第二个参数被传入,据我所知,第二个参数是可选的这个参数但是反转并不需要它传递给它的原因?如果没有它,代码似乎工作得很好,所以我缺少什么。

2 个答案:

答案 0 :(得分:2)

随着Mike Bostock幸运地对GitHub问题#173 Simplify / clarify rescaleX and rescaleY.做出了回应,这个问题终于可以解决:

  

答案是:这是JavaScript的良好做法。如果对象的方法恰好是绑定到对象的,则不必指定 this ,但是除非记录了文档(并且在将来的版本中不太可能更改),否则通常不应该这样做。 / p>

答案 1 :(得分:0)

edit :好吧,我的猜想最终是错误的,请参见other answer


发布了这个非常有趣的问题两年后,我瞥见了解决这个谜题的可能方法。但是,仍然有很多假设:只有该代码的作者Mike Bostock才有真正的答案(前提是他仍然记得为什么要这样做)。

如OP所述,thisArg函数中的此map是不相关的:

x.domain(s.map(x2.invert, x2));
//this bit here -----------^

这是因为刻度的invert方法不需要this值。

但是,如果我们在同一代码的下方再看几十行,就会发现:

context.select(".brush").call(brush.move, x.range().map(t.invertX, t));

在这里我们再次找到thisArg

x.range().map(t.invertX, t)
//thisArg ---------------^

如果我们将invertX的{​​{3}}来看,原因是invertX需要一个值来用作this

invertX: function(x) {
    return (x - this.x) / this.k;
}

这里是我的假设:invertinvertX是非常相似的名字,尽管Bostock发明了它们并编写了无数D3代码,他还是混淆了两者并设置了{{1} }(thisArg),尽管没有必要,但它不会破坏代码,并且未被作者发现。

另一个支持这种假设的论点是,在两种情况下,他都将对象用作x2.invert。比较:

thisArg