Как написать именованную функцию стрелки в ES2015?
у меня есть функция, которую я пытаюсь преобразовать в новый синтаксис стрелки в ES6. Это именованная функция:
function sayHello(name) {
console.log(name + ' says hello');
}
есть ли способ дать ему имя без оператора var:
var sayHello = (name) => {
console.log(name + ' says hello');
}
очевидно, что я могу использовать эту функцию только после того, как я ее определил. Что-то вроде следующего:
sayHello = (name) => {
console.log(name + ' says hello');
}
есть новый способ сделать это в ES6?
7 ответов:
Как написать именованную функцию стрелки в 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 Error at foo (http://stacksnippets.net/js:14:23) at http://stacksnippets.net/js:17:3Примечание
foo.name is: foo
иError...at foo
.на Chrome 50 и ранее, Firefox 52 и ранее, и Edge без экспериментального флага, вы увидите это вместо этого, потому что у них нет
Function#name
собственность (пока):foo.name is: Error at foo (http://stacksnippets.net/js:14:23) at 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
Я не говорю, что красиво, но это работает, если вы абсолютно, положительно нужна одна оболочка выражения.
нет. Синтаксис стрелки-это сокращенная форма для анонимных функций. Анонимные функции, ну, анонимны.
имени функции определяются с помощью
function
ключевое слово.
Если под "именем" вы подразумеваете, что хотите
.name
свойство вашей функции стрелки должно быть установлено, вам повезло.Если функция стрелки определена в правой части выражения присваивания, движок возьмет имя в левой части и использует его для установки функции стрелки
.name
, например,var sayHello = (name) => { console.log(name + ' says hello'); } sayHello.name //=== 'sayHello'
сказав это, ваш вопрос, кажется, больше "могу ли я получить функцию стрелки для подъема?'. Боюсь, что ответ на этот вопрос будет большим "нет".
похоже, что это будет возможно с ES7: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions
данный пример:
class PostInfo extends React.Component { handleOptionsButtonClick = (e) => { this.setState({showOptionsModal: true}); } }
тело функций стрелки ES6 имеет тот же лексический это, что и код, который их окружает, что дает нам желаемый результат из-за того, что инициализаторы свойств ES7 ограничены.
обратите внимание, что для получения этой работы с babel мне нужно было включить самый экспериментальный синтаксис ES7 stage 0. В моем веб-пакете.конфиг.js-файл я обновил загрузчик babel следующим образом:
{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},
вы можете пропустить часть функции и часть стрелки для создания функций. Пример:
class YourClassNameHere{ constructor(age) { this.age = age; } foo() { return "This is a function with name Foo"; } bar() { return "This is a function with name bar"; } } let myVar = new YourClassNameHere(50); myVar.foo();