我一直在编写 d3
代码,最终有很多这样的函数:
selection.attr('x', function(d) { return d.layout.x; });
有什么方法可以模拟 Scala 的占位符语法,这样我就可以这样写:
selection.attr('x', _.layout.x);
显然,getter 需要被告知要应用的特定参数名称,或者可以定义一种“元 getter”,它用获取所需命名属性的匿名函数进行响应。
我有兴趣知道是否存在类似的东西,例如,CoffeeScript。 ES6 lambda 函数更接近,但仍然不如占位符语法语义和清晰。
最佳答案
您没有说明您希望它在什么环境中运行,因此,假设 the bleeding edge没关系,我们使用Proxy
:
var _ = new Proxy({}, {
get: function(target, name) {
return createProxyForPath(name, []);
}
});
function createProxyForPath(name, path) {
var newPath = path.slice();
newPath.push(name);
return new Proxy({}, {
get: function(target, name) {
if (name !== "$") return createProxyForPath(name, newPath);
return function getter(obj) {
return newPath.reduce(function(prev, curr) {
return prev[curr];
}, obj);
};
},
apply: function(target, context, args) {
// TODO: Preserve function calls and args here
}
});
}
你可以像这样使用它:
> [{x: 1}, {x: 2}, {x: 3}].map(_.x.$)
[1, 2, 3]
它并不能完全替代 Scala 的神奇下划线(例如,它现在不会捕获方法调用,因此您不能执行 _.x.toString().slice(0, 3)
举一个例子)。此外,它需要一个显式的 $
来表示链的结束。但对于简单的 getter 来说它效果很好。
或者,如果您现在需要支持 Firefox 以外的浏览器,您可以编写 sweet.js macro改为生成 getter:
// Via Daniel
macro _ {
rule { . $m ... } => { function (value) { return value.$m ... } }
}
selection.attr('x', _.layout.x + 1);
将扩展为:
selection.attr('x', function(value) {
return value.layout.x + 1;
});
(如果您自己在 sweet.js 函数中使用 value
,则会 do the right thing 并将参数重命名为 value$some-integer
以避免函数内的任何名称冲突匿名函数。)
它确实处理方法调用,但当然这些方法都不能处理使用占位符作为函数参数:
selection.attr('x', someFunction(_));
关于javascript - JavaScript 中匿名函数的占位符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24177294/