如何在ES2015中编写命名箭头功能?

时间:2015-01-16 04:55:32

标签: 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) => {
        console.log(name + ' says hello');
    }

ES6 中有新的方法吗?

9 个答案:

答案 0 :(得分:176)

  

如何在ES2015中编写命名箭头功能?

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

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

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

这是在Assignment Operators > Runtime Semantics: Evaluation中定义的,它调用the abstract SetFunctionName operation(该调用目前在步骤1.e.iii中)。

同样,Runtime Semantics: PropertyDefinitionEvaluation调用SetFunctionName,从而为此函数提供了一个真正的名称:

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

现代引擎为已经如此的语句设置函数的内部名称; Edge仍然在运行时标志后面的函数实例上将其作为name使用。

例如,在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);
}

在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: fooError...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现在有它; Edge让它落后于旗帜,大概它不会在旗帜后面停留更长时间。

  

显然,我只能在定义后使用此功能

正确。箭头函数没有函数声明语法,只有函数表达式语法,并且在旧式命名函数表达式中没有等效于该名称的箭头({{1} })。所以没有相当于:

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

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

答案 1 :(得分:86)

没有。箭头语法是匿名函数的简写形式。匿名函数是匿名的。

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

答案 2 :(得分:44)

如果通过'named'表示你想要设置箭头函数的.name属性,那么你很幸运。

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

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

sayHello.name //=== 'sayHello'

话虽如此,你的问题似乎更多“我可以获得一个箭头功能来提升吗?”。这个问题的答案是一个很大的“不”,我很害怕。

答案 3 :(得分:0)

看来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语法。在我的webpack.config.js文件中,我像这样更新了babel加载器:

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

答案 4 :(得分:0)

实际上,命名箭头功能的一种方法(至少从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

答案 5 :(得分:-1)

为了编写命名箭头函数你可以在下面的示例中找到一个名为LoginClass的类,在这个类中我写了一个名为successAuth箭头,名为function     class LoginClass {

    constructor() {

    }

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

    }

}

答案 6 :(得分:-1)

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

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

答案 7 :(得分:-1)

正如 Jörg 提到的,箭头函数不能命名。

如果您需要一个名称以获得更好的调用堆栈(变量名称,例如来自其他答案的 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

答案 8 :(得分:-3)

这是ES6

是的,我认为你之后的事情是这样的:

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