我有一个函数,我试图转换为 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 中有新的方法吗?
答案 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: 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现在有它; 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);
}
答案 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"