Javascript 如何在ES2015中编写命名箭头函数?
我有一个函数,我正试图将其转换为ES6中的新箭头语法。它是一个命名函数: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)
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里找不到