【问题标题】:Javascript double colon lambdaJavascript 双冒号 lambda
【发布时间】:2018-02-05 20:05:38
【问题描述】:

我知道在 Java 中有一个双冒号 (::) lambda,它允许您编写如下回调:Stream.of(new Object(), new Object()).map(Object::toString)

所以我想知道是否有 Babel 插件或任何其他方式在 Javascript (NodeJS) 中有类似的 lambda?

编辑:不仅仅是原生对象。 (例如:Person::name

【问题讨论】:

  • Javascript 本身就支持这一点,因为函数是一流的对象。但要小心this

标签: javascript node.js lambda babeljs


【解决方案1】:

Java 方法可以是静态的,也可以不是静态的,参数和返回值由类型提示和已知的编译时间决定。 JavaScript 函数可以作为方法或静态调用,甚至是同一个函数,并且不知道进出什么样的类型,甚至没有设置参数的数量。由于无法进行类型推断,因此您需要清楚地说明您将要做什么:

[{}, {}].map(o => o.toString());
; ==> [ '[object Object]', '[object Object]' ]

如果你只是引用函数:

[{}, {}].map(Object.prototype.toString);
; ==> [ '[object Undefined]', '[object Undefined]' ]

原因是对象作为参数传递,Object.prototype.toString("something") 尝试在函数上下文中使用this,即undefined。因为它没有被称为方法。不过,您可以创建一个功能来满足您的需求:

function mapMember(fn) {
  return (v) => fn.call(v);
}

[{}, {}].map(mapMember(Object.prototype.toString));
// ==> [ '[object Object]', '[object Object]' ]

我觉得这过于冗长,所以我倾向于使用字符串:

function mapMember(str) {
  return v => v[str]();
}
[{}, {}].map(mapMember('toString'));
// ==> [ '[object Object]', '[object Object]' ]

使用相同的方法,您可以轻松地制作一个获取字段的变体:

function mapProperty(str) {
  return v => v[str];
}
[{test: 'hello'}, {test: 'world'}].map(mapProperty('test'));
// ==> [ 'hello', 'world' ]

或者你可以两者都做:

function mapObject(str) {
  return v => typeof v[str] === 'function' ? v[str]() : v[str];
}
[{test: 'hello'}, { test() { return 'world!'; } }].map(mapObject('test'));
// ==> [ 'hello', 'world' ]

这样做的限制是您永远不能收集成员函数,因为它们将被应用。

请注意,有很多方法可以做到这一点,因此这只是一个如何将抽象应用于您的代码的示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-04
    • 2015-10-17
    • 1970-01-01
    • 2010-12-03
    • 2019-09-14
    • 2018-04-04
    相关资源
    最近更新 更多