JavaScript 中的一个特性似乎使我能够避开"正确"的方式。
与其写d.foo
和d.bar
还能够写d["foo"]
和d["bar"]
。
在大多数使用场景中,任何一种形式都可以,但在下面的代码中
function f(myscale, foo_or_bar) {
blah.attr(myscale(d => d[foo_or_bar]));
}
f(foo_scale, "foo");
f(bar_scale, "bar");
我能够发送一个字符串来指示应该访问一个或另一个成员。
当然,这里我只有一个语句(blah.attr
),它不保证定义/使用函数,但在实践中它更实质性,并且确实保证了一个共同的定义。
事实上,上面的代码看起来很糟糕,以至于发送布尔标志is_it_foo
并编写一个if
语句以在d.foo
和d.bar
之间进行选择不会更糟。
组合两条线的正确(函数式编程)方法是什么
blah.attr(foo_scale(d => d.foo));
blah.attr(bar_scale(d => d.bar));
合二为一?
(我已经看到了在交换两个参数的同时发送函数的技巧;但正如你从这个问题中可以看出的那样,我还没有在野外掌握这项技术,甚至可能在理论上也没有掌握
。更新
我基本上是在寻找一个Lisp或Scheme专家,然后他选择了JavaScript。对于这个人来说,这个问题将是一个琐碎而即时的练习。如果像我一样,你的引力仍然在C++/Java世界中,请和我一起等待有人来阐明。(对于"关闭"的选民,如果 Scheme/Lisp 的人也表示这个问题没有意义,并且传递字符串来提取成员是完全可以的,我会很乐意删除这个问题。
与其将属性名称作为字符串传递,不如将属性 getter 函数作为参数传递给f
:
function f(myscale, get) {
blah.attr(myscale(get));
}
f(foo_scale, d => d.foo);
f(bar_scale, d => d.bar);
对于每个键foo
如果你有一个唯一的映射器函数foo_scale
,那么你目前的做法是正确的方法:
blah.attr(foo_scale(d => d.foo);
blah.attr(bar_scale(d => d.bar);
这更像是一种代码设计模式,而不是Javascript功能。因为这不仅会增强代码的可读性,还可以让你随意改变任何键的功能。
但是假设你所有的键都映射到一个映射器函数scale
,你可以这样做:
const keys = ["foo", "bar"]
keys.forEach((key) => {
blah.attr1(scale(d => d[foo_or_bar]);
blah.attr2(scale2(d => d[foo_or_bar]);
blah.attr3(scale3(d => d[foo_or_bar]);
})
理想情况下,这是一个很好的模式,如果您能够将常见模式概括为单个方法,则可以使用它scale