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

Javascript 如何在ES2015中编写命名箭头函数?,javascript,ecmascript-6,arrow-functions,Javascript,Ecmascript 6,Arrow Functions,我有一个函数,我正试图将其转换为ES6中的新箭头语法。它是一个命名函数: function sayHello(name) { console.log(name + ' says hello'); } 有没有一种方法可以在不使用var语句的情况下为其命名: var sayHello = (name) => { console.log(name + ' says hello'); } 显然,我只能在定义了这个函数之后才能使用它。大致如下: sayHello = (name)

我有一个函数,我正试图将其转换为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中是否有一种新的方法可以做到这一点?

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


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

ES7似乎可以做到这一点:

举例如下:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}
ES6 arrow函数体与围绕它们的代码共享相同的词法,这使我们获得了所需的结果,因为ES7属性初始值设定项的作用域是这样的

请注意,要使用babel实现这一点,我需要启用最具实验性的ES7阶段0语法。在我的webpack.config.js文件中,我更新了babel加载程序,如下所示:

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

如果“named”是指希望设置arrow函数的
.name
属性,那么您就很幸运了


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

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

sayHello.name //=== 'sayHello'

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

这是ES6

是的,我想你想要的是这样的:

const foo = (depth) => {console.log("hi i'm Adele")}
foo -> // the function itself
foo() -> // "hi i'm Adele"
如何在ES2015中编写命名箭头函数

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

根据规范,此函数具有真实名称,
sayHello

var sayHello = name => {
    console.log(name + ' says hello');
};
这是在调用的位置定义的(该调用当前在步骤1.e.iii中)

类似地,调用
SetFunctionName
,从而为该函数提供一个真实名称:

let o = {
    sayHello: name => {
        console.log(`${name} says hello`);
    }
};
现代引擎已经为这样的语句设置了函数的内部名称;Edge仍然有一个位,使其在运行时标志后面的函数实例上可用作
name

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

“严格使用”;
让foo=()=>{throw new Error();};
log(“foo.name是:”+foo.name);
试一试{
foo();
}捕获(e){
console.log(e.stack);

}
为了编写命名的arrow函数,您可以参考下面的示例,其中我有一个名为LoginClass的类,在这个类中我编写了一个名为的arrow函数,名为
successAuth
类登录类{

    constructor() {

    }

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

    }

}

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

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

实际上,命名arrow函数(至少从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);
}

如前所述,箭头函数无法命名

如果您需要一个名称以获得更好的调用堆栈(来自其他答案的变量名,如
const foo…
,将不会出现在调用堆栈中),并且您不想使用函数关键字,请使用对象

export const baz = {
    foo(bar) {
        alert(`I am in a ${bar}!`);
    }
}
基本上,从可读性的角度来看,导入后会更好:

baz.foo('bar') 
// vs
foo('bar') // could look like a local function

箭头点语法不是为了不给函数命名吗?不一定,箭头函数保持词法范围,因此有一个速记来生成命名函数(对堆栈跟踪有用)使用词法作用域会非常有用第二个代码段有什么问题?您当然可以在函数体中引用指定的名称:var sayHello=(name)=>{console.log(sayHello);};在递归函数的情况下,您通常会这样做。这不是一个非常有用的示例,但这里有一个函数,如果没有得到它的参数,它会返回自己:var sayHello=(name)=>name?console.log(name+'sayshello'):sayHello;sayHello()('frank');//->“frank says hello”与问题的内容相比,问题的标题具有极大的误导性,因为您已经排除了命名arrow函数的方式(这是第二个片段)。这不是一个命名的arrow函数。这是一个在构造函数中创建实例方法的快捷方式,我想知道它在这里有什么关系?嗨@Bergi,我不确定这是否是原作者的意图,但我试图创建一个与对象具有相同作用域的命名函数。如果我们不使用此技术,我们将nt要有适当的作用域,我们必须将其放入类构造函数中。
this.handleOptionsButtonClick=this.handleOptionsButtonClick.bind(this);
Uh,您可以同样轻松地使用
constructor(){this.handleOptionsButtonClick=(e)=>{…}
这完全等同于您答案中的代码,但在ES6中已经起作用。无需使用
.bind
。顺便说一句,我认为您将“命名函数”与“(实例)方法”和“范围”与“
上下文”混淆了@tdecs:是的,您可以;Jörg搞错了。
让a=()=>{}
定义了一个名为
a
的命名箭头函数。至少在当前的chrome版本中,sayHello.name仍然是“”;请注意,与所有函数一样,sayHello是一个对象,因此您可以根据需要为其定义任意属性。您不能写入“name”,因为它是只读的,但您可以说hello.my_name=“sayHello”;不确定这会让您得到什么,因为您不能在函数体中执行/引用它。我错了:虽然名称不是直接可变的,但您可以这样配置它:Object.defineProperty(sayHello,'name',{value:'sayHello'})“如果在右侧定义了箭头函数[…]”这是什么来源?我在s里找不到