web-dev-qa-db-ja.com

2つの等号(==)と3つの等号(===)のJavaScriptパフォーマンスの違い

JavaScriptでは、2つのイコール(_==_)を使用する場合と3つのイコール(_===_)を使用する場合でパフォーマンスに違いはありますか?

例:if (foo == bar) vs if (foo === bar)

40
Eric

厳密な比較(===)は常にわずかに速くなりますが、 通常、差は無視できます です。

比較で型強制を必要としないことが確実にわかっている場合は、===を選択することは間違いなく理にかなっています。常に少なくとも==と同じくらい高速です。

29
Dave Ward
  • 比較されるタイプが同じである場合、they are同一です。つまり、彼らはまったく同じアルゴリズムを使用しています。

  • タイプがdifferentの場合、パフォーマンスは無関係です。型強制が必要か、不要か。必要ない場合は、==を使用しないでください。予期しない結果になる場合があります。

41
user1034768

編集:参考のために、仕様による仕様によるアクセル博士による説明Rauschmayer http://www.2ality.com/2011/06/javascript-equality.html 本当に素晴らしい記事です。

_===_(厳密な等価性):同じタイプの等しい値のみを考慮します。

  1. undefined === undefined、null === null、
  2. NaN ===それ自体を含めて何もない、
  3. プリミティブ[数値|文字列|ブール] ===プリミティブ値が等しい、
  4. 自己(+0 === -0)
  5. 2つのオブジェクト[配列|オブジェクト|関数] ===自己のみ(まったく同じエンティティ)

_==_(緩やかな平等)

  1. 両方の値が同じタイプの場合:===と比較してください。
  2. 未定義== null
  3. 数値と文字列:文字列=>数値と比較
  4. ブール値と非ブール値=>非ブール値を数えて比較
  5. 文字列または数値=>オブジェクト:オブジェクトをプリミティブおよび比較に変換します。

最新のすべてのJavascript環境では、それらの実装はまったく異なります。簡単に言えば、_==_は、指定された変数をプリミティブ(文字列、数値、ブール値)に変換することによって類似性をテストします。 _===_は、厳密に同じかどうかをテストします。これは、変換せずにまったく同じオブジェクトまたはプリミティブ値を意味​​します。

_objOne == objTwo_を実行すると、実際に発生するのは[[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())です。

ValueOfの解決は多少複雑になる可能性があり、JSで公開されている関数と内部エンジンのものの間で跳ね返ります。比較では常に2つの値がプリミティブに強制変換されるか、エラーがスローされると言うだけで十分です。

編集:EQUALSは実際に_STRICT_EQUALS_を最初に試行し、残りのプロセスを先取りします。

ここで興味深いのは、valueOf(およびそのパートナーtoString)がオーバーライド可能であることです。このコードをChromeで実行します(JSCとV8がこの一口を共有しているかどうかは不明ですが、Webkitだと思います)。

_var actions = [];
var overload = {
  valueOf: function(){
    var caller = arguments.callee.caller;
    actions.Push({
      operation: caller.name,
      left: caller.arguments[0] === this ? "unknown" : this,
      right: caller.arguments[0]
    });
    return Object.prototype.toString.call(this);
  }
};
overload.toString = overload.valueOf;
overload == 10;
overload === 10;
overload * 10;
10 / overload;
overload in window;
-overload;
+overload;
overload < 5;
overload > 5;
[][overload];
overload == overload;
console.log(actions);
_

出力:

_[ { operation: 'EQUALS',
    left: overload,
    right: 10 },
  { operation: 'MUL',
    left: overload,
    right: 10 },
  { operation: 'DIV',
    left: 'unknown',
    right: overload },
  { operation: 'IN',
    left: overload,
    right: DOMWindow },
  { operation: 'UNARY_MINUS',
    left: overload,
    right: undefined },
  { operation: 'TO_NUMBER',
    left: overload,
    right: undefined },
  { operation: 'COMPARE',
    left: overload,
    right: 5 },
  { operation: 'COMPARE',
    left: 'unknown',
    right: overload },
  { operation: 'ToString',
    left: 'unknown',
    right: overload } ]
_

_==_と_===_の違いの本質は、_===_がリストに表示されていないことで示されています。それは完全にJavascriptLandへの旅をスキップします。パフォーマンスを比較すると、その冒険は費用がかかります。

ただし、エンジンの最適化を考慮する必要があります。ほとんどのオブジェクトでは、エンジンはほとんどの手順を省略してNativeLandにとどまり、ほぼ同じパフォーマンスを得ることができます。しかし、これは保証ではなく、何かがエンジンによる最適化の使用を妨げる場合、コードの一部の奇妙さ、またはビルトインまたは無数の問題をオーバーライドすると、すぐにパフォーマンスの結果がわかります。 _===_はそれを強制します。

_===_は、Javascriptで唯一不変のものです。

14
user748221

パフォーマンスにより、======よりも厳密であるため、==の方がパフォーマンスが優れていると思います。

例えばChromeコンソールで以下を試してください。

> 1 == '1'
  true
> 1 === '1'
  false

=====より多くのものをチェックする必要があります

2
James.Xu

いくつかの薄っぺらなテストから、=====よりもわずかに速いようです。

ほんのわずかですが、何百万ものテストの繰り返しで数ミリ秒の違いが見られることを意味します。手元のタスクに最も適したものを使用するのではなく、パフォーマンスの向上はおそらく必要ありません。

編集:実際には、比較している/ what /とブラウザの実装に依存しているようです。つまり、心配する必要はありません。

1
Hamish

比較されるアイテムによって異なります。 「===」は「==」よりも厳密なので、「==」よりも速くfalseを返す必要があります。ただし、2つの項目が完全に等しい場合、「===」は「==」よりも時間がかかるはずです。これは、等しいかどうかより多くのプロパティをチェックする必要があるためです。

0
Joseph C