变量与表达式作为Javascript参数

Variables vs Expressions as Javascript Arguments

本文关键字:Javascript 参数 表达式 变量      更新时间:2023-09-26

将参数作为表达式传递,而不是首先将其作为变量,是否存在性能问题?

someFunction( x+2 );

与。

var total = x+2;
someFunction( total );

函数呢?

someFunction( someOtherFunction() );

否。更重要的是,这种微观优化(几乎可以肯定)毫无意义。

话虽如此,如果你不止一次使用表达式的结果,那么保存计算结果可能会有一些完全无法察觉的、完全不值得担心的好处。

把它写得可读。别担心这些东西。

显而易见的是:生成一个变量会创建一个变量。这会消耗内存,并且在执行时会消耗一些时间。之后,它要么需要时间来进行垃圾收集,要么在函数泄漏时不释放内存。

但是,您不会注意到任何差异。在这个水平上,绩效是无法衡量的。经验法则:当您真正需要变量时,或者当它们提高代码的可读性时,请使用它们。

尽管差异很小,但答案实际上是特定于实现的;JavaScript引擎在分配东西的方式上几乎可以肯定是不同的。但是,我可以告诉您,这些差异很可能与大多数其他语言中的差异相似,我可以在调试器中检查这些语言的内存和处理器寄存器。让我们看看一个场景:

var sum = x+2;
someFunction(sum);

这会分配内存来保存sum,只要函数在作用域中,sum就会一直存在。如果函数最终成为一个闭包,那么这可能是永远的。在递归函数中,这可能很重要。

someFunction(x+2);

在大多数语言中,这将在堆栈上计算x+2,并将结果传递给someFunction。没有留下任何记忆。

对于函数返回值,答案将完全相同。

综上所述:

  1. 确切的答案取决于JavaScript引擎的实现。

  2. 很可能你不会注意到性能差异。

  3. 当结果被重复使用时,或者当您希望在调试器中轻松检查结果时,您可能希望使用变量。

这主要是个人喜好的问题。

与不创建局部变量并直接将表达式作为函数的参数写入函数相比,创建一个作用域不超出当前函数的局部变量不会产生任何成本。事实上,没有什么告诉您编写someFunction(x*2)不会被javascript编译器转换为在内部将变量绑定到x*2结果的代码-事实上,许多编译器和JIT使用SSA作为其中间表示之一,在这种形式下,变量总是绑定到每个子表达式的结果。请参阅相关的维基百科条目。无论是否处于闭合状态,都没有区别。

在引入新变量和直接将表达式写成自变量之间做出选择时,只有两个相关的问题需要注意:

  1. 可读性:命名表达式的结果是否会使表达式的计算内容更加清晰;

  2. 计算表达式的成本:如果要多次编写表达式,则将变量绑定到结果将需要重用,避免每次都重新计算结果。如果您的表达式预计需要很长时间才能计算,则这仅与相关。

如果你只需要在函数定义中写一次表达式,那么将变量绑定到结果可能会使结果在内存中的生存时间比严格要求的要长,但这几乎总是完全无关的:大多数函数调用的生存时间都很短,在许多情况下,结果不会占用太多内存,并且在函数退出时会回收堆栈上分配的内存,然后垃圾收集器会很快回收堆中分配的内存。