我有一个函数要转换为 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中 是否有新方法可以做到这一点?
如何在ES2015中编写命名箭头功能?
您可以按照在问题中排除的方式进行操作:将其放在赋值或属性初始化程序的右侧,在该赋值或属性初始化程序中,JavaScript引擎可以合理地将变量或属性名称用作名称。没有 其他 方法可以执行此操作,但是这样做是正确的,并且在规范中已完全涵盖。
根据规范,此函数的真实名称为sayHello:
sayHello
var sayHello = name => { console.log(name + ' says hello'); };
这在“ _赋值运算符” >“运行时语义:评估”_中定义,在其中调用抽象SetFunctionName操作(该调用当前在步骤1.e.iii中)。
SetFunctionName
类似地,运行时语义:PropertyDefinitionEvaluation调用SetFunctionName,因此为该函数提供了真实的名称:
let o = { sayHello: name => { console.log(`${name} says hello`); } };
现代引擎已经为类似的语句设置了函数的内部名称。Edge仍然具有在name运行时标志后面的功能实例上使其可用的功能。
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是:foo 错误 在foo(http://stacksnippets.net/js:14:23) 在http://stacksnippets.net/js:17:3
注意foo.name is: foo和Error...at foo。
foo.name is: foo
Error...at foo
在Chrome 50和更早的版本,Firefox 52和更早的版本以及没有实验标记的Edge上,您会看到它,因为它们还没有此Function#name属性:
Function#name
foo.name是: 错误 在foo(http://stacksnippets.net/js:14:23) 在http://stacksnippets.net/js:17:3
需要注意的是名字是从丢失foo.name is:,但它 是 在堆栈跟踪中。只是,实际上在功能上实现name 属性的优先级低于某些其他ES2015功能;Chrome和Firefox现在拥有它;Edge将其放在标志后面,大概不会再停留在标志后面了。
foo.name is:
显然,我只能在定义此功能后使用它
正确。没有箭头函数的函数 声明 语法,只有函数 表达式 语法,并且没有等效于旧式命名函数表达式(var f = function foo() {};)中名称的箭头。因此,它不等于:
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));
当然,如果 必须 将其放在需要单个表达式的地方,则始终可以…使用箭头函数:
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
我并不是说那很漂亮,但是如果您绝对需要一个单独的表达式包装器,它就可以工作。