如何在ES2015中写一个命名箭头函数? [英] How do I write a named arrow function in ES2015?
问题描述
我有一个功能,我试图转换为 ES6 中的新的箭头语法。它是一个命名函数:
function sayHello(name){
console.log(name +'said hello' );
}
有没有办法给它一个名字:
var sayHello =(name)=> {
console.log(name +'said hello');
}
显然,在定义它之后,我只能使用这个函数。如下所示:
sayHello =(name)=> {
console.log(name +'said hello');
}
有没有一种新的方法在 ES6 ?
如何在ES2015中编写命名箭头函数?
您可以按照您在问题中排除的方式进行操作:将其放在作业或属性初始化程序的右侧,其中的变量或属性名称可以合理地用作JavaScript引擎的名称。没有其他的方式可以做到这一点,但是这样做是正确的,并且完全被规范所涵盖。
根据规范,这个函数有一个真实的名称, sayHello
:
var sayHello = name => {
console.log(name +'said hello');
};
这是在 赋值运算符>运行时语义:评估 a href =http://www.ecma-international.org/ecma-262/6.0/index.html#sec-setfunctionname =noreferrer>摘要 SetFunctionName
操作(该通话正在步骤1.e.iii)。
同样地, 运行时语义:PropertyDefinitionEvaluation 调用 SetFunctionName
,从而给这个函数一个真正的名字:
let o = {
sayHello:name => {
console.log(`$ {name} said 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及更高版本(以及具有实验标志的边缘13及以上版本)上,pre>
<当你运行时,你会看到:
foo.name是:foo
错误
在foo http://stacksnippets.net/js:14:23)
at http://stacksnippets.net/js:17:3
注意 foo.name是:foo
和错误...在foo
。
在Chrome 50及更早版本的Firefox 52及更早版本中,Edge没有实验标志,您会看到这一点,因为它们没有 Function#名称
属性(还):
foo.name是:
错误
foo(http://stacksnippets.net/js:14:23)
at http://stacksnippets.net/js:17:3
请注意, foo.name中缺少该名称:
,但显示为堆栈跟踪。只是实际上实现 c $ c> name 属性的功能比其他ES2015功能的优先级要低; Chrome和Firefox现在有了;边缘有一个国旗后面,大概不会在国旗后面长很多。
显然,我只能使用这个功能在我定义之后
正确。对于箭头函数没有函数声明语法,只有函数表达式语法,并且没有与旧式命名函数表达式中的名称相等的箭头( var f = function foo(){};
)。所以没有等同于:
console.log(function fact(n) {if(n <0){throw new Error(Not defined for negative number);} return n == 0?1:n * fact(n - 1);}(5)); // 120
你必须将其分解成两个表达式(我反对你应该这么做 ):
let fact = n => {if(n <0){throw new Error(Not defined for negative number); } return n == 0? 1:n * fact(n-1);}; console.log(fact(5));
当然,如果您将放在需要单个表达式的位置,则可以随时使用箭头函数:
console.log((()=> {let fact = n => {if (n)(n)()()()()()()()()() ); // 120
我不是说'很漂亮,如果你绝对需要一个单一的表达式包装器,它会起作用。
I have a function that I am trying to convert to the new arrow syntax in ES6. It is a named function:
function sayHello(name) {
console.log(name + ' says hello');
}
Is there a way to give it a name without:
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?
How do I write a named arrow function in 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 other way to do it, but doing that is correct and fully covered by the specification.
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).
Similiarly, Runtime Semantics: PropertyDefinitionEvaluation calls SetFunctionName
and thus gives this function a true name:
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.
For example, in Chrome or Firefox, open the web console and then run this snippet:
"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:
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
.
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):
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.
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:
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.
这篇关于如何在ES2015中写一个命名箭头函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!