如何在ES2015中写一个命名箭头函数? [英] How do I write a named arrow function in ES2015?

查看:333
本文介绍了如何在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆