JavaScript中的匿名函数的占位符 [英] Placeholders for anonymous functions in JavaScript
问题描述
我一直在写 d3
代码,最终会有很多这样的功能:
selection.attr('x',function(d){return d.layout.x;});有没有什么方法来模拟Scala的占位符语法,这将允许我这样写: selection.attr('x',_.layout.x);
显然getter需要被告知要应用的特定参数名称,或者可以定义一种'meta-getter'用一个匿名函数来响应,获得所需的命名属性。
我想知道如果这样的东西存在于, CoffeeScript。 ES6 lambda函数更接近,但仍然不像语法和清楚的占位符语法。
解决方案希望这样运行,因此,假设流血的边缘是好的,让我们使用 代理
:
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:保存函数调用和args here
}
}
}
您可以这样使用:
> [{x:1},{x:2},{x:3}]。map(_。x。$)
[1,2,3]
这不是Scala的魔术下划线的完全替代(例如,它不会捕获方法调用,所以你不能做 _。x.toString()。slice(0,3)
以一个例子)。此外,它需要一个明确的 $
来表示链的结束。
或者,如果你需要支持不是Firefox的浏览器,现在你可以写一个 sweet.js宏来生成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;
});
(如果您使用 value
function sweet.js将,并将参数重命名为 value $ some-integer
,以避免匿名函数中的任何名称冲突。)
它处理方法调用,但是当然没有这些方法使用占位符来处理例如函数参数:
selection.attr('x',someFunction(_));
I've been writing d3
code that ends up having lots of functions like this:
selection.attr('x', function(d) { return d.layout.x; });
Is there any way to simulate Scala's placeholder syntax, which would allow me to write this:
selection.attr('x', _.layout.x);
Obviously getters need to be told a specific parameter name to apply to, or one could define a sort of 'meta-getter' that responds with an anonymous function that gets the desired named attribute.
I'd be interested to know if anything like this exists in, for example, CoffeeScript. ES6 lambda functions are closer, but still not as semantic and clear as placeholder syntax.
解决方案 You don't say what environment you want this to run in, so, assuming that the bleeding edge is okay, let's use 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
}
});
}
You would use it like this:
> [{x: 1}, {x: 2}, {x: 3}].map(_.x.$)
[1, 2, 3]
It's not a complete replacement for Scala's magic underscore (it doesn't trap method calls right now, for example, so you can't do _.x.toString().slice(0, 3)
to take one example). Also, it requires an explicit $
to signal the end of the chain. But for simple getters it works pretty well.
Alternately, if you need to support browsers that aren't Firefox right now you could write a sweet.js macro to generate the getter instead:
// Via Daniel
macro _ {
rule { . $m ... } => { function (value) { return value.$m ... } }
}
selection.attr('x', _.layout.x + 1);
Will expand to:
selection.attr('x', function(value) {
return value.layout.x + 1;
});
(If you use value
yourself in the function sweet.js will do the right thing and rename the argument to value$some-integer
to avoid any name conflicts inside the anonymous function.)
It does handle method calls, but of course none of these approaches handle using the placeholder as, for example, a function argument:
selection.attr('x', someFunction(_));
这篇关于JavaScript中的匿名函数的占位符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!