Как написать именованную функцию стрелки в 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 152

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();

для того, чтобы написать именованную функцию стрелки вы можете товарищ ниже пример, где у меня есть класс с именем LoginClass и внутри этого класса я написал стрелка с именем функции, по имени successAuth класс LoginClass {

    constructor() {

    }

    successAuth = (dataArgs)=> { //named arow function

    }

}

ЭТО ES6

Да, я думаю, что вы после чего-то вроде этого:

const foo = (depth) => {console.log("hi i'm Adele")}
foo -> // the function itself
foo() -> // "hi i'm Adele"