o [str] vs(o => o.str)

时间:2017-12-21 11:43:41

标签: javascript optimization v8

我正在编写一个函数,它使对象和投影知道它必须在哪个字段上工作。

我想知道我是否应该使用这样的字符串:

const o = {
  a: 'Hello There'    
};


function foo(o, str) {
  const a = o[str];
  /* ... */    
}

foo(o, 'a');

或使用功能:

function bar(o, proj) {
  const a = proj(o);
  /* ... */
}

bar(o, o => o.a);

我认为V8正在用我的javascript对象创建类。如果我使用字符串动态访问字段,它是否仍然能够使用我的对象而不是哈希表或其他东西创建一个类?

1 个答案:

答案 0 :(得分:2)

V8开发者在这里。答案是"我应该使用哪种模式?"很可能"它取决于"。根据你应用的行为,我可以想到一个或另一个(可能)更快(一点点)的场景。因此,我建议您尝试两者(在实际代码中,而不是微基准测试!)并自己测量,或者只是选择您喜欢的和/或在更大的上下文中更有意义,而不用担心它直到分析显示这个是一个值得花时间的实际瓶颈。

如果在呼叫站点确实知道这些属性,那么最快的选择可能是在呼叫之前加载该属性:

function baz(o, str, a) {
  /* ... */
}

baz(o, "a", o.a);

我意识到如果事情真的如此简单,你可能不会问这个问题;如果这个假设是正确的,那么这就是微基准测试的简化如何能够轻易改变正确答案的一个很好的例子。

类问题的答案是,这个决定对V8如何代表你的对象没有影响 - 这主要取决于你如何修改你的对象,而不是你如何阅读它们。另外,对于记录:

  • 每个对象都有一个"隐藏的类&#34 ;;它是否使用哈希表表示与
  • 正交
  • 哈希表模式或形状跟踪模式对于任何给定对象是否更好是依赖于用例的事情之一,这正是两种模式存在的原因。我不会过分担心它,除非你知道(从剖析中)它在你的情况下恰好是一个问题(通常情况下,V8的启发式方法是正确的;人工干预很少是必要的)。