如何在ES2015中编写一个命名为arrow的函数?

时间:2021-08-09 15:45:29

I have a function that I am trying to convert to the new arrow syntax in ES6. It is a named function:

我有一个函数,我试着在ES6中转换为新的箭头语法。它是一个命名函数:

function sayHello(name) {
    console.log(name + ' says hello');
}

Is there a way to give it a name without a var statement:

是否有一种方法可以不用var语句给它命名:

var sayHello = (name) => {
    console.log(name + ' says hello');
}

Obviously, I can only use this function after I have defined it. Something like following:

显然,我只能在定义了这个函数之后才能使用它。类似的:

sayHello = (name) => {
        console.log(name + ' says hello');
    }

Is there a new way to do this in ES6?

在ES6中是否有新的方法来实现这一点?

7 个解决方案

#1


140  

How do I write a named arrow function in ES2015?

如何在ES2015中编写一个命名为arrow的函数?

You do it the way you ruled out in your question: You put it on the right-hand side of an assignment or property initializer where the variable or property name can reasonably be used as a name by the JavaScript engine. There's no other way to do it, but doing that is correct and fully covered by the specification.

您可以使用您在问题中排除的方法:将它放在赋值或属性初始化器的右边,在那里,变量或属性名可以被JavaScript引擎合理地用作名称。没有其他方法可以做到这一点,但是这样做是正确的,规范也完全涵盖了这一点。

Per spec, this function has a true name, sayHello:

根据规范,这个函数有一个真实的名字,说你好:

var sayHello = name => {
    console.log(name + ' says hello');
};

This is defined in Assignment Operators > Runtime Semantics: Evaluation where it calls the abstract SetFunctionName operation (that call is currently in step 1.e.iii).

这在赋值操作符>运行时语义中定义:在其中调用抽象SetFunctionName操作(该调用目前在步骤1.e.iii中)。

Similiarly, Runtime Semantics: PropertyDefinitionEvaluation calls SetFunctionName and thus gives this function a true name:

类似地,运行时语义:PropertyDefinitionEvaluation调用SetFunctionName,因此给这个函数一个真实的名称:

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};

Modern engines set the internal name of the function for statements like that already; Edge still has the bit making it available as name on the function instance behind a runtime flag.

现代引擎已经为这样的语句设置了函数的内部名称;Edge仍然有位使它在运行时标志后面的函数实例上作为名称可用。

For example, in Chrome or Firefox, open the web console and then run this snippet:

例如,在Chrome或Firefox中,打开web控制台,然后运行以下代码片段:

"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

On Chrome 51 and above and Firefox 53 and above (and Edge 13 and above with an experimental flag), when you run that, you'll see:

在Chrome 51和上面,火狐53和上面(边13和上面有一个实验标记),当你运行时,你会看到:

foo.name is: foo
Error
    at foo (http://stacksnippets.net/js:14:23)
    at http://stacksnippets.net/js:17:3

Note the foo.name is: foo and Error...at foo.

注意页脚的名称是:foo and Error…在foo。

On Chrome 50 and earlier, Firefox 52 and earlier, and Edge without the experimental flag, you'll see this instead because they don't have the Function#name property (yet):

在Chrome 50和更早的版本中,Firefox 52和更早的版本中,以及没有实验标志的Edge中,你会看到这个,因为它们还没有函数#name属性(还没有):

foo.name is: 
Error
    at foo (http://stacksnippets.net/js:14:23)
    at http://stacksnippets.net/js:17:3

Note that the name is missing from foo.name is:, but it is shown in the stack trace. It's just that actually implementing the name property on the function was lower priority than some other ES2015 features; Chrome and Firefox have it now; Edge has it behind a flag, presumably it won't be behind the flag a lot longer.

注意,foo.name是:,但是它在堆栈跟踪中显示。只是在函数上实现name属性的优先级比其他ES2015特性要低;Chrome和火狐都有;Edge在一面旗帜后面,大概不会在国旗后面很久了。

Obviously, I can only use this function after I have defined it

显然,我只能在定义了这个函数之后才能使用它

Correct. There is no function declaration syntax for arrow functions, only function expression syntax, and there's no arrow equivalent to the name in an old-style named function expression (var f = function foo() { };). So there's no equivalent to:

正确的。箭头函数没有函数声明语法,只有函数表达式语法,也没有与旧式命名函数表达式中的名称等价的箭头(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

You have to break it into two expressions (I'd argue you should do that anyway):

你必须把它分成两个表达(我认为你无论如何都应该这么做):

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

Of course, if you have to put this where a single expression is required, you can always...use an arrow function:

当然,如果你必须把它放在需要一个表达式的地方,你总是可以……使用箭头功能:

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

I ain't sayin' that's pretty, but it works if you absolutely, positively need a single expression wrapper.

我不是说这很漂亮,但如果你绝对需要一个表达式包装,它就能工作。

#2


88  

No. The arrow syntax is a shortform for anonymous functions. Anonymous functions are, well, anonymous.

不。箭头语法是匿名函数的简短形式。匿名函数是匿名的。

Named functions are defined with the function keyword.

命名函数是用function关键字来定义的。

#3


40  

If by 'named', you mean you want the .name property of your arrow function to be set, you're in luck.

如果你的意思是你想要你的箭头函数的。name属性被设置,你就很幸运了。

If an arrow function is defined on the right-hand-side of an assignment expression, the engine will take the name on the left-hand-side and use it to set the arrow function's .name, e.g.

如果在赋值表达式的右侧定义了一个箭头函数,那么引擎将取左侧的名称,并使用它设置箭头函数的.name,例如。

var sayHello = (name) => {
    console.log(name + ' says hello');
}

sayHello.name //=== 'sayHello'

Having said that, your question seems to be more 'can I get an arrow function to hoist?'. The answer to that one is a big ol' "no", I'm afraid.

话虽如此,你的问题似乎更多的是“我能得到一个箭头函数来提升吗?”恐怕这个问题的答案是“不”。

#4


0  

It appears that this will be possible with ES7: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions

看起来这是有可能的,ES7: https://babeljs.io/blog/2015/06/07/- on-es6 + #arrow-functions。

The example given is:

给出的例子是:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

The body of ES6 arrow functions share the same lexical this as the code that surrounds them, which gets us the desired result because of the way that ES7 property initializers are scoped.

ES6箭头函数的主体与围绕它们的代码共享相同的词法,这使我们得到所需的结果,因为ES7属性初始化器的作用域是这样的。

Note that to get this working with babel I needed to enable the most experimental ES7 stage 0 syntax. In my webpack.config.js file I updated the babel loader like so:

请注意,要使这个与babel一起工作,我需要启用最具实验性的ES7 stage 0语法。在我webpack.config。我更新了babel加载程序,如下所示:

{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},

#5


0  

You could skip the function part and the arrow part to create functions. Example:

您可以跳过函数部分和箭头部分来创建函数。例子:

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

#6


-1  

in order to write named arrow function you can fellow the bellow example, where I have a class named LoginClass and inside this class I wrote an arrow named function, named successAuth class LoginClass {

为了写命名箭头函数你可以用下面这个例子,我有一个类名为LoginClass在这个类中我写了一个名为function的箭头,命名为successAuth类LoginClass {

    constructor() {

    }

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

    }

}

#7


-3  

THIS IS ES6

这是ES6

Yeah I think what you're after is something like this:

是的,我认为你想要的是这样的东西:

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

#1


140  

How do I write a named arrow function in ES2015?

如何在ES2015中编写一个命名为arrow的函数?

You do it the way you ruled out in your question: You put it on the right-hand side of an assignment or property initializer where the variable or property name can reasonably be used as a name by the JavaScript engine. There's no other way to do it, but doing that is correct and fully covered by the specification.

您可以使用您在问题中排除的方法:将它放在赋值或属性初始化器的右边,在那里,变量或属性名可以被JavaScript引擎合理地用作名称。没有其他方法可以做到这一点,但是这样做是正确的,规范也完全涵盖了这一点。

Per spec, this function has a true name, sayHello:

根据规范,这个函数有一个真实的名字,说你好:

var sayHello = name => {
    console.log(name + ' says hello');
};

This is defined in Assignment Operators > Runtime Semantics: Evaluation where it calls the abstract SetFunctionName operation (that call is currently in step 1.e.iii).

这在赋值操作符>运行时语义中定义:在其中调用抽象SetFunctionName操作(该调用目前在步骤1.e.iii中)。

Similiarly, Runtime Semantics: PropertyDefinitionEvaluation calls SetFunctionName and thus gives this function a true name:

类似地,运行时语义:PropertyDefinitionEvaluation调用SetFunctionName,因此给这个函数一个真实的名称:

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};

Modern engines set the internal name of the function for statements like that already; Edge still has the bit making it available as name on the function instance behind a runtime flag.

现代引擎已经为这样的语句设置了函数的内部名称;Edge仍然有位使它在运行时标志后面的函数实例上作为名称可用。

For example, in Chrome or Firefox, open the web console and then run this snippet:

例如,在Chrome或Firefox中,打开web控制台,然后运行以下代码片段:

"use strict";
let foo = () => { throw new Error(); };
console.log("foo.name is: " + foo.name);
try {
  foo();
} catch (e) {
  console.log(e.stack);
}

On Chrome 51 and above and Firefox 53 and above (and Edge 13 and above with an experimental flag), when you run that, you'll see:

在Chrome 51和上面,火狐53和上面(边13和上面有一个实验标记),当你运行时,你会看到:

foo.name is: foo
Error
    at foo (http://stacksnippets.net/js:14:23)
    at http://stacksnippets.net/js:17:3

Note the foo.name is: foo and Error...at foo.

注意页脚的名称是:foo and Error…在foo。

On Chrome 50 and earlier, Firefox 52 and earlier, and Edge without the experimental flag, you'll see this instead because they don't have the Function#name property (yet):

在Chrome 50和更早的版本中,Firefox 52和更早的版本中,以及没有实验标志的Edge中,你会看到这个,因为它们还没有函数#name属性(还没有):

foo.name is: 
Error
    at foo (http://stacksnippets.net/js:14:23)
    at http://stacksnippets.net/js:17:3

Note that the name is missing from foo.name is:, but it is shown in the stack trace. It's just that actually implementing the name property on the function was lower priority than some other ES2015 features; Chrome and Firefox have it now; Edge has it behind a flag, presumably it won't be behind the flag a lot longer.

注意,foo.name是:,但是它在堆栈跟踪中显示。只是在函数上实现name属性的优先级比其他ES2015特性要低;Chrome和火狐都有;Edge在一面旗帜后面,大概不会在国旗后面很久了。

Obviously, I can only use this function after I have defined it

显然,我只能在定义了这个函数之后才能使用它

Correct. There is no function declaration syntax for arrow functions, only function expression syntax, and there's no arrow equivalent to the name in an old-style named function expression (var f = function foo() { };). So there's no equivalent to:

正确的。箭头函数没有函数声明语法,只有函数表达式语法,也没有与旧式命名函数表达式中的名称等价的箭头(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

You have to break it into two expressions (I'd argue you should do that anyway):

你必须把它分成两个表达(我认为你无论如何都应该这么做):

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

Of course, if you have to put this where a single expression is required, you can always...use an arrow function:

当然,如果你必须把它放在需要一个表达式的地方,你总是可以……使用箭头功能:

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

I ain't sayin' that's pretty, but it works if you absolutely, positively need a single expression wrapper.

我不是说这很漂亮,但如果你绝对需要一个表达式包装,它就能工作。

#2


88  

No. The arrow syntax is a shortform for anonymous functions. Anonymous functions are, well, anonymous.

不。箭头语法是匿名函数的简短形式。匿名函数是匿名的。

Named functions are defined with the function keyword.

命名函数是用function关键字来定义的。

#3


40  

If by 'named', you mean you want the .name property of your arrow function to be set, you're in luck.

如果你的意思是你想要你的箭头函数的。name属性被设置,你就很幸运了。

If an arrow function is defined on the right-hand-side of an assignment expression, the engine will take the name on the left-hand-side and use it to set the arrow function's .name, e.g.

如果在赋值表达式的右侧定义了一个箭头函数,那么引擎将取左侧的名称,并使用它设置箭头函数的.name,例如。

var sayHello = (name) => {
    console.log(name + ' says hello');
}

sayHello.name //=== 'sayHello'

Having said that, your question seems to be more 'can I get an arrow function to hoist?'. The answer to that one is a big ol' "no", I'm afraid.

话虽如此,你的问题似乎更多的是“我能得到一个箭头函数来提升吗?”恐怕这个问题的答案是“不”。

#4


0  

It appears that this will be possible with ES7: https://babeljs.io/blog/2015/06/07/react-on-es6-plus#arrow-functions

看起来这是有可能的,ES7: https://babeljs.io/blog/2015/06/07/- on-es6 + #arrow-functions。

The example given is:

给出的例子是:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

The body of ES6 arrow functions share the same lexical this as the code that surrounds them, which gets us the desired result because of the way that ES7 property initializers are scoped.

ES6箭头函数的主体与围绕它们的代码共享相同的词法,这使我们得到所需的结果,因为ES7属性初始化器的作用域是这样的。

Note that to get this working with babel I needed to enable the most experimental ES7 stage 0 syntax. In my webpack.config.js file I updated the babel loader like so:

请注意,要使这个与babel一起工作,我需要启用最具实验性的ES7 stage 0语法。在我webpack.config。我更新了babel加载程序,如下所示:

{test: /\.js$/, exclude: /node_modules/, loader: 'babel?stage=0'},

#5


0  

You could skip the function part and the arrow part to create functions. Example:

您可以跳过函数部分和箭头部分来创建函数。例子:

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

#6


-1  

in order to write named arrow function you can fellow the bellow example, where I have a class named LoginClass and inside this class I wrote an arrow named function, named successAuth class LoginClass {

为了写命名箭头函数你可以用下面这个例子,我有一个类名为LoginClass在这个类中我写了一个名为function的箭头,命名为successAuth类LoginClass {

    constructor() {

    }

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

    }

}

#7


-3  

THIS IS ES6

这是ES6

Yeah I think what you're after is something like this:

是的,我认为你想要的是这样的东西:

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