JavaScript中的匿名函数的占位符 [英] Placeholders for anonymous functions in JavaScript

查看:122
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆