0

I've been playing with the new ECMAScript 6 features and this question has to do with arrow functions. The following code is a simple functional composition method assigned to the Function object's prototype. It works perfectly well using a simple anonymous function but does not when using an arrow function instead.

Function.prototype.compose = function (bar) {
    var foo = this;
    return function () {
        return foo(bar.apply(null, arguments));
    };
};

var addFive = function (baz) {
    return baz + 5;
};

var addTen = function (hello) {
    return hello + 10;
};

var addFifteen = addFive.compose(addTen);

console.log(addFifteen(10));

http://jsfiddle.net/oegonbmn/

Function.prototype.compose = function (bar) {
    var foo = this;
    return () => foo(bar.apply(null, arguments));
};

var addFive = function (baz) {
    return baz + 5;
};

var addTen = function (hello) {
    return hello + 10;
};

var addFifteen = addFive.compose(addTen);

console.log(addFifteen(10));

http://www.es6fiddle.com/hyo32b2p/

The first one logs 25 correctly to the console whereas the second one logs function (hello) { return hello + 10; }105 which doesn't exactly tell me what I'm doing wrong.

I am not returning the value within the arrow function since it is supposed to implicitly return the very last statement (the first and last in this instance) and I suppose the issue at hand has something to do with the lexical scoping and the values of this, maybe. Can anyone explain?

hippietrail
  • 13,703
  • 15
  • 87
  • 133
Siddharth
  • 1,086
  • 3
  • 13
  • 28

1 Answers1

2

Both this and arguments are not (re)bound in arrow functions, but instead lexically scoped. That is, you get whatever they are bound to in the surrounding scope.

In ES6, using arguments is deprecated anyway. The preferred solution is to use rest parameters:

Function.prototype.compose = function (bar) {
  return (...args) => this(bar.apply(null, args));
};

or, in fact:

Function.prototype.compose = function (bar) {
  return (...args) => this(bar(...args));
};
Andreas Rossberg
  • 31,309
  • 3
  • 55
  • 70
  • Okay. This is great. Thank you. One last question. Does this mean that there is no arguments property on arrow functions? Or that the arguments property is bound to the value of the arguments property of the surrounding function or in case of no function, undefined? – Siddharth Aug 10 '14 at 10:25
  • 1
    The arguments _property_ on functions is a broken legacy misfeature, which, for good reasons, has never been standardised. I don't think any VM vendor has the intention of proliferating it to arrow functions. It will simply not exist. – Andreas Rossberg Aug 10 '14 at 10:40
  • 1
    Neither will `.caller` and `.callee`, btw. – Andreas Rossberg Aug 10 '14 at 10:41
  • Okay. Got it. Thank you! So to access parameters besides named ones, the rest parameters are a best practice from ES6 onwards. Am I correct? – Siddharth Aug 10 '14 at 11:03