Почему возврат этого выражения функции стрелки ECMAScript Harmony приводит к неожиданному поведению?

Я играл с новыми функциями ECMAScript 6, и этот вопрос связан с функциями стрелок. Следующий код представляет собой простой метод функциональной композиции, назначенный прототипу объекта Function. Он отлично работает при использовании простой анонимной функции, но не при использовании функции стрелки.

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/

Первый правильно регистрирует 25 в консоли, тогда как второй регистрирует функцию (hello) { return hello + 10; }105, которая точно не говорит мне, что я делаю неправильно.

Я не возвращаю значение в стрелочной функции, поскольку предполагается, что она неявно возвращает самый последний оператор (первый и последний в этом случае), и я полагаю, что проблема связана с лексической областью действия и значениями этого , может быть. Кто-нибудь может объяснить?


person Siddharth    schedule 10.08.2014    source источник


Ответы (1)


И this, и arguments не (повторно) связаны в стрелочных функциях, а вместо этого имеют лексическую область действия. То есть вы получаете все, к чему они привязаны в окружающей области.

В ES6 использование arguments в любом случае не рекомендуется. Предпочтительным решением является использование остальных параметров:

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

или, на самом деле:

Function.prototype.compose = function (bar) {
  return (...args) => this(bar(...args));
};
person Andreas Rossberg    schedule 10.08.2014
comment
Хорошо. Это здорово. Спасибо. Последний вопрос. Означает ли это, что у стрелочных функций нет свойства arguments? Или что свойство arguments привязано к значению свойства arguments окружающей функции или, в случае отсутствия функции, undefined? - person Siddharth; 10.08.2014
comment
Аргументы свойства в функциях — это сломанная устаревшая функция, которая по уважительным причинам никогда не была стандартизирована. Я не думаю, что какой-либо поставщик виртуальных машин намерен распространить его на функции стрелок. Его просто не будет. - person Andreas Rossberg; 10.08.2014
comment
Как и .caller и .callee, кстати. - person Andreas Rossberg; 10.08.2014
comment
Хорошо. Понятно. Спасибо! Таким образом, для доступа к параметрам, помимо именованных, рекомендуется использовать остальные параметры, начиная с ES6. Я прав? - person Siddharth; 10.08.2014