Javascript 如何在 ES2015 中编写命名箭头函数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27977525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:02:20  来源:igfitidea点击:

How do I write a named arrow function in ES2015?

javascriptecmascript-6arrow-functions

提问by jhamm

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 中是否有一种新方法可以做到这一点?

回答by T.J. Crowder

How do I write a named arrow function in ES2015?

如何在 ES2015 中编写命名箭头函数?

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 otherway to do it, but doing that is correct and fully covered by the specification.

您按照您在问题中排除的方式进行操作:您将它放在赋值或属性初始值设定项的右侧,其中变量或属性名称可以合理地用作 JavaScript 引擎的名称。没有其他方法可以做到这一点,但这样做是正确的,并且完全包含在规范中。

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

根据规范,这个函数有一个真实的名字,sayHello

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

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

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

Similiarly, Runtime Semantics: PropertyDefinitionEvaluationcalls SetFunctionNameand 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 nameon the function instance behind a runtime flag.

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

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 及更高版本和 Firefox 53 及更高版本(以及带有实验标志的 Edge 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: fooand Error...at foo.

注意foo.name is: fooError...at 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#nameproperty (yet):

在 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

Note that the name is missing from foo.name is:, but it isshown in the stack trace. It's just that actually implementing the namepropertyon 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 is:,但它在堆栈跟踪中。只是实际在函数上实现name属性的优先级低于其他一些 ES2015 特性;Chrome 和 Firefox 现在拥有它;Edge 有它在旗帜后面,大概它不会在旗帜后面太久了。

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

很明显,我只能在定义之后才能使用这个函数

Correct. There is no function declarationsyntax for arrow functions, only function expressionsyntax, 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 haveto 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.

我不是说这很漂亮,但如果您绝对,肯定需要一个单一的表达式包装器,它就可以工作。

回答by J?rg W Mittag

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

不。箭头语法是匿名函数的缩写。匿名函数是匿名的。

Named functions are defined with the functionkeyword.

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

回答by hughfdHymanson

If by 'named', you mean you want the .nameproperty 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.

话虽如此,您的问题似乎更像是“我可以得到一个箭头函数来提升吗?”。恐怕这个答案是一个很大的“不”。

回答by Hamish Currie

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/react-on-es6-plus#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 箭头函数的主体与围绕它们的代码共享相同的词法 this,由于 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.js 文件中,我像这样更新了 babel 加载器:

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

回答by Devin G Rhode

Actually it looks like one way to name arrow functions (at least as of chrome 77...) is to do this:

实际上,命名箭头函数的一种方法(至少从 chrome 77 开始......)是这样做的:

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

enter image description here

enter image description here

回答by BERGUIGA Mohamed Amine

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 successAuthclass LoginClass {

为了编写命名箭头函数,您可以参考下面的示例,其中我有一个名为 LoginClass 的类,在这个类中我编写了一个名为 function箭头,名为successAuthclass LoginClass {

    constructor() {

    }

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

    }

}

回答by scre_www

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

回答by Venkatesh Namburi

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"