Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript double colon lambda

I know that in Java there is a double colon (::) lambda which permits you to write callback like following: Stream.of(new Object(), new Object()).map(Object::toString).

So I was wondering if there is a Babel plugin or any other way to have a similar lambda in Javascript (NodeJS)?

Edit: Not just with native Object. (Ex: Person::name)

like image 734
Elie G. Avatar asked Oct 17 '22 23:10

Elie G.


1 Answers

A Java method can either be static or not and the arguments and return is determined by type hinting and known compile time. A JavaScript function can be called as a method or static, even the same function, and have no idea what kind of types goes in or out and even the number of arguments is not set. Since no type inference can be done you need to state clearly what you are going to do:

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

If you were to just reference the function:

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

The reason is that the objects are passed as arguments and Object.prototype.toString("something") tries to use this which is undefined in a functional context. since it was not called as a method. You could make a function that does what you want though:

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

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

I find that overly verbose so I tend to use strings:

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

With the same method you can easily make a variant that fetches fields:

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

Or you can do both:

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

The limitation of this is that you can never collect member functions since they will be applied.

Please note that there are many ways to do this so this is just an example of how to apply abstraction to your code.

like image 194
Sylwester Avatar answered Oct 21 '22 03:10

Sylwester