匿名函数 VS 常量函数 - JavaScript

5

接下来是关于这个讨论的内容:

我对 JavaScript 中的函数声明有一些疑问。

通过匿名函数声明,我指的是像这样的内容 (https://en.wikibooks.org/wiki/JavaScript/Anonymous_Functions):

var myFunction = function (fruit){
    alert('I like ' + fruit);
}

在这里,const的意思是:

const myfunction = (fruit) => alert('I like ' fruit);

使用匿名函数还是const更快?我读过在JavaScript中使用const可以进行编译优化。有没有任何理由让我使用其中之一而不是另一个呢?

这是否相关呢?


2
除非您正在循环中创建数千个函数,否则我怀疑这不会有任何影响。使用语义上正确的即可。 - James Thorpe
我被踩是因为什么? - Flame_Phoenix
我曾经认为优化主要是客观的。如果你不喜欢我的问题,那没关系,但说它是愚蠢或构造不良的问题则远非事实。 - Flame_Phoenix
2
这种优化,即使你确定它是可能的,通常也没有必要担心。情况 - 特别是对于像JavaScript这样正在积极发展的语言 - 可能会随着编译器或运行时系统的下一个版本而改变。追求微小的“优化”不值得花费相似的精力来提高算法性能所能带来的一小部分收益。 - Pointy
1
“通过匿名函数声明,我指的是像这样的东西:” 这不是匿名函数。它是一个使用名称 myFunction函数声明。(作为声明,它不需要在末尾加上 ;。) - T.J. Crowder
显示剩余6条评论
1个回答

12

匿名函数 VS const 函数

大概你是在比较

var func = function() { };
// or
let func = function() { };

使用

const func = function() { };

主要原因并非为了优化。而是通过代码记录您永远不打算更改func,并让引擎保护您免受意外更改的影响。(我还应该指出,截至ES2015,没有一个这些函数是匿名的。它们全部都有名称func,因为ES2015根据上下文添加了一些规则,用于为通过“匿名”函数表达式创建的函数分配名称,包括上面的简单赋值规则。)
但是关于优化:
与大多数JavaScript优化问题一样,答案是:取决于情况。理论上,如果您从不打算更改func中的值,则使用const意味着JavaScript引擎可以选择在假定该值永远不会更改的情况下进行优化。请注意,它并不免除引擎处理符号在嵌套作用域或类似情况中被遮蔽的可能性。
引擎是否实际根据该值不会更改的知识以有意义的方式进行优化,将取决于引擎的实现,并且很可能会因引擎而异。
无论是通过常量还是变量查找函数以调用它是否更快,这将取决于引擎的实现方式。
任何绝对差异是否转化为程序中的实际收益,将取决于上述因素、程序的结构、使用该函数的频率、查找时间与函数实际执行时间的比较(例如,是否超负荷)等等。
这取决于具体情况。 :-)
如果您遇到了查找时间导致实际问题的情况,请进行分析并查看其是否有所不同。

关于你的编辑:

By anonymous function declaration I mean something like this:

function myFunction(fruit){
    alert('I like ' + fruit);
};

and by const I mean this:

const myfunction = (fruit) => alert('I like ' fruit);

第一个函数不是匿名函数。(实际上,两个都不是。) 它是一个通过函数声明创建的名为myFunction的函数。(作为声明,末尾没有必要加上;。) 函数声明不能创建匿名函数,¹名称是声明的必需部分。²

话虽如此,一旦函数被创建(这与我上面展示的表达式发生在不同的时间),它的行为非常像var func = ...示例,就func的解析方式、是否可以更改func等方面而言。

你的第二个示例与第一个示例有三个重要的不同之处:

  1. 它将函数引用分配给常量。

  2. 它使用箭头函数,而不是一个普通的 function 函数(由于没有更好的术语,我将其称为“简单”函数)。

  3. 你的箭头函数版本返回调用 alert 的结果(因为你在箭头函数上使用了 简洁体)。你的声明版本则没有。

我们已经处理了 #1 的任何性能方面。我怀疑 #3 不太可能有影响。

关于#2(它是箭头函数):理论上调用箭头函数比调用简单函数需要更少的工作。引擎不必设置arguments伪对象,也不必创建this绑定。但是如果箭头函数使用this,则需要更多的工作来查找它(就像外部作用域中的变量一样)。但是再次强调,这只是理论;只要没有副作用,引擎可以进行优化。例如,如果您的代码中未使用arguments,现代引擎会避免为简单函数创建它。我预计在箭头函数使用this方面进行优化会非常好,因为他们看到的this在函数存在后不能改变。

所以(等待一下):这取决于情况。


¹ "函数声明不能创建匿名函数" - 有一件事似乎是这个规则的例外,那就是 export default function() { /*...*/ }; 是一个没有显式名称的函数声明(是的,真的),但使用了名称default,所以它不会创建匿名函数。

² "......名称是声明的必要部分..." 除了上面的export default例子。那是唯一的例外。


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