Как мне написать именованную функцию стрелки в ES2015?
Вы делаете это так, как исключили в своем вопросе: вы помещаете его в правую часть инициализатора присваивания или свойства, где имя переменной или свойства может быть разумно использовано в качестве имени движком JavaScript. Нет другого способа сделать это, но это правильно и полностью отражено в спецификации.
По спецификации у этой функции есть настоящее имя sayHello
:
var sayHello = name => {
console.log(name + ' says hello');
};
Это определено в Операторы присваивания> Семантика времени выполнения: оценка, где она вызывает абстрактную SetFunctionName
операцию (этот вызов в настоящее время находится на шаге 1.e.iii).
Аналогично, семантика времени выполнения: PropertyDefinitionEvaluation вызывает SetFunctionName
и, таким образом, дает этой функции истинное имя:
let o = {
sayHello: name => {
console.log(`${name} says hello`);
}
};
Современные движки уже устанавливают внутреннее имя функции для таких операторов; У Edge все еще есть бит, делающий его доступным как name
на экземпляре функции позади флага времени выполнения.
Например, в Chrome или Firefox откройте веб-консоль и запустите этот фрагмент:
"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
foo();
} catch (e) {
console.log(e.stack);
}
На Chrome 51 и выше и Firefox 53 и выше (и Edge 13 и выше с экспериментальным флагом), когда вы запустите это, вы увидите:
foo.name is: foo
ошибка
в foo (http://stacksnippets.net/js:14:23)
на http://stacksnippets.net/js:17:3
Обратите внимание на foo.name is: foo
и Error...at foo
.
В Chrome 50 и более ранних версиях, Firefox 52 и более ранних версиях и Edge без экспериментального флага вы увидите это вместо этого, потому что у них нет Function#name
свойства (пока):
Имя foo.name:
ошибка
в foo (http://stacksnippets.net/js:14:23)
на http://stacksnippets.net/js:17:3
Обратите внимание , что имя отсутствует foo.name is:
, но это будет показано в трассировке стека. Просто на самом деле реализация name
свойства функции имела более низкий приоритет, чем некоторые другие функции ES2015; Chrome и Firefox теперь есть; У Эджа есть это позади флага, вероятно, это не будет позади флага намного дольше.
Очевидно, что я могу использовать эту функцию только после того, как я определил ее
Верный. Не существует синтаксиса объявления функций для функций стрелок, только синтаксис выражений функций , и нет стрелки, эквивалентной имени в названном выражении функции старого стиля ( var f = function foo() { };
). Так что нет эквивалента:
console.log(function fact(n) {
if (n < 0) {
throw new Error("Not defined for negative numbers");
}
return n == 0 ? 1 : n * fact(n - 1);
}(5)); // 120
Вы должны разбить его на два выражения (я бы сказал, что вы должны это делать в любом случае ) :
let fact = n => {
if (n < 0) {
throw new Error("Not defined for negative numbers.");
}
return n == 0 ? 1 : n * fact(n - 1);
};
console.log(fact(5));
Конечно, если вам нужно поместить это туда, где требуется одно выражение, вы всегда можете ... использовать функцию стрелки:
console.log((() => {
let fact = n => {
if (n < 0) {
throw new Error("Not defined for negative numbers.");
}
return n == 0 ? 1 : n * fact(n - 1);
};
return fact(5);
})()); // 120
Я не говорю, что это красиво, но это работает, если вам абсолютно и безусловно нужна единая оболочка для выражений.