const 与内联字符串文字,编译优化

const vs inline string literal, compilation optimisation

这不是问题,而是基于代码结构对 V8 优化的探索。


我和另一位开发人员正在讨论 const 字符串文字与内联字符串文字 在 V8 编译优化方面的价值。 当然,假设我们始终处于 严格模式

这里有一些代码示例放在上下文中:

常量

const NAME = "something";
function doSomething(s) {
  return NAME + s;
}

内联字符串

function doSomething(s) {
  return "something" + s;
}

我们同意的内容:
- const 为 魔法值 提供更多上下文,从而简化维护。

我们不同意的地方:

稍微考虑一下我会倾向于同意他的观点......每次调用函数时都会重新实例化字符串文字,但这可以很容易地被 V8 优化并在后续调用中避免。但是,我对编译器和编译器优化不是很了解。

任何人都可以阐明这一点吗?

这里是 V8 开发人员。

内联字符串在所有函数调用之间共享,即使在未优化的代码中也是如此,因此无需担心 re-instantiations。 通常,对于 JS 引擎来说,确定文字永远不会改变是微不足道的(因为它们是文字,呃!)。 const 并没有你想象的那么多保证,因为 JavaScript 很复杂(例如:

function makeFunction(val) { 
  const NAME = val; 
  function doSomething(s) { 
    return NAME + s;
  }
  return doSomething;
}
var doSomething = makeFunction("something");
var doAnything = makeFunction("anything, really");

在这里,const NAME 并不是您直觉上所说的常数 ;-))。

也就是说,这两种方法之间的差异可能太小而无关紧要。在您的代码中做任何更有意义的事情。


旁注:对于比字符串或数字更复杂的对象,情况会有所不同。例如。这个:

function getSomething() { return "something"; }
function doSomething(s) { return getSomething() + s; }

显然比这更有效:

function doSomething(s) {
  function getSomething() { return "something"; }
  return getSomething() + s;
}

因为在那种情况下,JS 引擎必须创建 "getSomething" 的新实例(或者花费大量的实现+计算努力来弄清楚这样做是可以避免的;我不会依赖那)。 不同之处在于对象身份的可观察性:

"a" === "a"  // true
(function f() {}) === (function f() {})  // false