匿名函数和命名函数作为对象键的值的区别

5

我使用Babel编译器将JSX转换为JavaScript。这是我感到好奇的一段代码。

getInitialState: function getInitialState() {
//List out different states that ListComponent could possibly have
return {
  showList: true,
  listType: this.props.type

在将JSX编译为JS之后,getInitialState是一个名为getInitialState()的方法。我不知道为什么它不是匿名方法。

原始代码:

getInitialState: function() {
//List out different states that ListComponent could possibly have
return {
  showList: true,
  listType: this.props.type

这样写有性能优势吗?

1
过去这使得调试更容易。现在调试器已经足够智能,可以推断名称,请参见http://astithas.com/talks/qconsf2013/#/18/2 - Oriol
@Oriol,这仍然比在整个堆栈跟踪中看到匿名函数被调用要好。 :P - toskv
对于递归函数或其他需要内部绑定标识符来引用自身的函数,这是(有些)重要的。 - Pointy
@Pointy 我原本以为函数内部的代码没有引用该名称。但是,是的,命名函数表达式替换了已弃用的 arguments.callee - Oriol
1
你展示了编译后的代码?原始源代码呢? - JMM
在ES6环境中,ES6确实确保许多函数的情况实际上获得了真正的名称,而不仅仅是堆栈跟踪中猜测的名称,因此调试器不必考虑它。例如:"如果hasNameProperty为false,则执行SetFunctionName(value,bindingId)。"以及规范中出现的大多数其他地方SetFunctionName - loganfsmyth
2个回答

8
除了文件大小可能会导致加载时间变长外,不会有性能损失。
给匿名函数命名可以帮助解决问题,因为这些名称在大多数浏览器的错误堆栈跟踪中出现。 这个 视频很好地解释了当您将名称设置为匿名函数时发生的情况。
此行为还包括在 ECMA262 ES6 语言规范中。您可以在这里查看。

非常感谢 @toskv。那真的帮助我理解了很多东西。 - Anvesh Checka
这是Ben Nadel关于此话题的视频链接。感谢@Oriol。https://vimeo.com/128582253 - Anvesh Checka
@AnveshChecka,这是一个非常好的解释为什么你应该给函数命名。你介意我把它包含在回答中吗? :) - toskv
2
对于那些好奇的人,虽然开发工具已经做了一段时间,但这种行为现在也是ES6规范的一部分:http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations-runtime-semantics-evaluation 请注意第6步:“如果hasNameProperty为false,则执行SetFunctionName(value,bindingId)。” - loganfsmyth
@toskv 请继续。 - Anvesh Checka

7
ES6规范定义了许多匿名函数的名称,基于函数的上下文,即使没有明确定义函数名称。以下是一些示例。
12.2.6.9: (链接)
var o = {foo: function(){}};
o.foo.name === 'foo';

12.14.4:

var foo;
foo = function(){};
foo.name === 'foo';

12.14.5.2:

var {foo = function(){}} = {};
foo.name === 'foo';

var [foo = function(){}] = [];
foo.name === 'foo';

12.14.5.3:

var foo;
([foo = function(){}] = []);
foo.name === 'foo'

12.15.5.4:

var foo;
({foo = function(){}} = {});
foo.name === 'foo'

13.3.1.4:

let foo = function(){};
foo.name === 'foo'

13.3.2.4:

var foo = function(){};
foo.name === 'foo'

13.3.3.6:

function fn([foo = function(){}]){
    foo.name === 'foo';
}
fn([]);

function fn2({foo = function(){}}){
    foo.name === 'foo';
}
fn2({});

14.1.19:

export default function(){};

import foo from './self'; // Made-up circular ref.
foo.name === 'default';

14.3.9:

var o = {foo(){}};
o.foo.name === 'foo';
class cls {foo(){}};
cls.prototype.foo.name === 'foo';

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接