JavaScript比較で使用する必要がある等号演算子(== vs ===)はどれですか?


5665

JavaScript を通過するためにJSLintを使用していて、内部を比較するようなことを行うと、==(2つの等号)を===(3つの等号)に置き換えるための多くの提案が返されidSele_UNVEHtype.value.length == 0ますifステートメントます。

交換にパフォーマンス上のメリットがある==とは、===

多くの比較演算子が存在するため、パフォーマンスの向上は歓迎されます。

タイプ変換が行われない場合、パフォーマンスが向上し==ますか?


134
誰にそれは同じ主題に興味があるかもしれません=== vs ==が、PHPで、ここで読むことができます:stackoverflow.com/questions/2401478/why-is-faster-than-in-php/...
マルコDemaio

257
念のために誰もが2012年に思っていた。===ある方法より速いです==jsperf.com/comparison-of-comparisons
Ry-

25
@minitechそれは型変換を行わないのであるはずです
UmurKontacı2012

19
@ minitech、===over を使用することでアプリケーションを著しく高速化することはできないと思います==。実際、ベンチマークは、最新のブラウザーの両方で大きな違いを示していません。個人的には、==厳密な平等が本当に必要でない限り、通常はどこでも使用します。
laurent

5
ここではクロックフォードさんの一部であるJSグッド部品彼は論じ話=====演算子は:youtube.com/...は、それが再生されない場合、それはATの夜03時20
davidhiggins

回答:


6486

厳密な等価演算子(===)は、抽象等価演算子(==、型変換が行われないこと、および型が等しいと見なされるために同じである必要があることを除い)します。

リファレンス:JavaScriptチュートリアル:比較演算子

==オペレータは、平等のために比較されます必要な型変換を行った後===オペレータはなりません二つの値が同じ型でない場合ので、変換を行い===、単純に返されますfalse。どちらも同様に高速です。

Douglas Crockfordの優れたJavaScript:The Good Partsを引用すると、

JavaScriptは、等価演算子の二組を持っています===!==、それらの邪悪な双子==!=。良いものはあなたが期待するように働きます。2つのオペランドの型が同じで値が同じ場合は、を===生成trueして!==生成しfalseます。悪魔の双子は、オペランドが同じ型であるときに正しいことを行いますが、それらが異なる型である場合、値を強制しようとします。彼らがそれを行うためのルールは複雑で、記憶に残るものではありません。これらは興味深いケースのいくつかです:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

平等比較表

推移性の欠如は憂慮すべきことです。私のアドバイスは、邪悪な双子を決して使用しないことです。代わりに、常にとを使用===してください!==。ここで示したすべての比較falseは、===演算子を使用して行われます。


更新:

オブジェクトに関する@Casebashのコメントと@Phillipe Laybaertの回答で良い点が取り上げられました。オブジェクトの場合、および(特別な場合を除いて)互いに一貫して作用します。 =====

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

特殊なケースは、プリミティブを、toStringまたはvalueOfメソッドが原因で、同じプリミティブに評価されるオブジェクトと比較する場合です。たとえば、文字列プリミティブと、Stringコンストラクターを使用して作成された文字列オブジェクトとの比較を検討してください。

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

ここで==オペレータは、2つのオブジェクトの値をチェックして返しているtrueが、===彼らは同じ型じゃないことを見て、返していますfalse。どちらが正しいか?それは本当にあなたが比較しようとしているものに依存します。私のアドバイスは、質問を完全にバイパスし、Stringコンストラクターを使用して文字列リテラルから文字列オブジェクトを作成しないことです。

リファレンス
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


237
タイプが同じである場合、===は速くありません。タイプが同じでない場合、===は変換を試みないため、より高速になります。
トカゲに請求する

521
===が==より遅くなることは決してありません。どちらも型チェックを行うので、===は==と比較して余分なことは何もしませんが、型チェックでは、型が同じでない場合に===がより早く終了する場合があります。
リザード

246
== /!=をすべて=== //!==に置き換えると、jsファイルのサイズが大きくなり、ロードに時間がかかります。:)
マルコデマイオ

92
「...彼らが行うルールは複雑で思い出に残るものです...」これで、このようなステートメントにより、プログラミング時にとても安全に感じるようになりました...
Johan

47
クロックフォードから:「推移性の欠如は憂慮すべきことです。」ソフトウェアを開発していて、比較演算子の警告で推移性の欠如が見つからない場合、または==と===の間の速度比較またはファイルサイズ/ロード時間が比較演算子の動作の推移的決定論よりも優先される場合は、戻って最初からやり直す必要があるかもしれません。
jinglesthula 2014年

1144

==演算子の使用(Equality

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

===演算子の使用(Identity

true === 1; //false
"2" === 2;  //false

これは、等価演算子==が型強制を行うためですを行うためです。つまり、インタープリターは、比較する前に暗黙的に値を変換しようとします。

一方、恒等演算子===は型強制を行わないため、比較時に値を変換しないため、1つのステップをスキップするので(このJSベンチマークテストによると)高速です。


9
@Software Monkey:値のタイプ(数値、ブール値など)は対象外
Philippe Leybaert、2009年

34
誰もJavascript Equality Tableについて言及していないので、ここにそれを示します:dorey.github.io/JavaScript-Equality-Table
blaze

6
最初のステートメントで、「true」が1に変換され、1がtrueに変換されていないことを確認しますか?
Shadi Namrouti 2016年

2
「平等」と「同一性」という用語はどこから来たのですか?標準ではこれらの用語は使用されていません。それは==「抽象的平等」と呼ばれ、===「厳密な平等」と呼ばれます。==あらゆる種類の「平等」と呼ぶのは、推移的ではないので、私見はひどいですが、なぜ変なのでしょうか。「アイデンティティ」についてはもっと問題があります。「うまくいく」が、この用語はかなり誤解を招くと思います。しかし真剣に、「アイデンティティ」という言葉を誰が作り出したのでしょうか。標準を検索しましたが、見つかりませんでした。
Ray Toal 2018

1
「同一性」は非常に間違った言葉です。私が使用したすべての言語でのID比較は、同じオブジェクト内の1つを意味します。つまり、2つの参照変数は、同等のエンティティだけでなく同じエンティティも指します。
イニゴ

724

間の等価比較の興味深い絵図=====

出典:http : //dorey.github.io/JavaScript-Equality-Table/


var1 === var2

===JavaScriptの等価性テストに使用する場合、すべてがそのままです。評価される前に何も変換されません。

JSでの===の同等性評価


var1 == var2

==JavaScriptの等価性テストに使用する場合、いくつかのファンキーな変換が行われます。

JSでの==の同等性評価

この話の教訓:

===行われる変換を完全に理解していない場合に使用してください==


3
@mfeineisつまり、==または!=ではなく===または!==です。新しいコーダーを混乱させたくない;)
katalin_2003

2
私の経験から、3つの等号を使用すると問題が発生する可能性があるため、完全に理解されていない限り回避する必要があります。2つのequalsを使用すると、99%の時間で型が等しくなることを望んでいないため、より良い結果が得られます。
vsync

13
@vsync:タイプを等しくしたくない場合3つのequals 使用する必要があります。
SNag 2017

7
例外:あなたが安全に使用できるx == nullかどうかを確認することxですnullundefined
アンディ

1
@ user648026:問題はvs との同等性比較についてです。大文字と小文字はいずれにしても等しくなく、および演算子の両方で返されます。また、キーワードは、、、、一つだけの場合にJSに存在し、上部または混合の場合に使用することができません。=====false=====truefalseundefinednullInfinity
SNag

609

ここでの答えでは、平等の意味については何も読みませんでした。これは同じで同じタイプの===意味であると言う人もいますが、それは本当ではありません。実際には、両方のオペランドが同じオブジェクトを参照するか、値タイプの場合は同じ値を持つことを意味します

そこで、次のコードを見てみましょう。

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

こっちも一緒:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

あるいは:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

この動作は常に明白であるとは限りません。ストーリーには、平等で同じタイプであることだけではありません。

ルールは:

:値の型(番号)が
a === b trueを返す場合ab同じ値を持ち、同じタイプのものです

参照タイプの
a === b場合まったく同じオブジェクトab参照している場合にtrueを返します

文字列の
a === b場合aとのb両方が文字列で、まったく同じ文字が含まれている場合にtrueを返します


文字列:特殊なケース...

文字列は値の型ではありませんが、JavaScriptでは値の型のように動作するため、文字列内の文字が同じで長さが同じ場合(「3番目の規則」で説明)、「等しい」ことになります。

今それは興味深いものになります:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

しかし、これはどうですか?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

文字列は値型のように動作すると思いましたか?まあ、それはあなたが誰に尋ねるかによります...この場合、aとbは同じ型ではありません。aタイプでありObjectながら、b型ですstringStringコンストラクタを使用して文字列オブジェクトを作成Objectすると、ほとんどの場合文字列として動作するタイプのオブジェクトが作成されることに注意してください。


6
activa:文字列がリテラルである場合にのみ、文字列が非常に等しいことを明確にします。新しいString( "abc")=== "abc"はfalseです(私の調査によると)。
ローレンスドル

3
new Number() == "0"。Firefoxでも:(function(){}) == "function () {\n}"
Thomas Eding、2011年

3
理由を説明していただきありがとうございますnew String("123") !== "123"。それらは異なるタイプです。シンプルですが混乱します。
スタイル

21
Stringオブジェクトは、他のオブジェクトと同様に文字列として動作しますnew String実際の文字列が作成されないため、使用しないでください。実際の文字列と文字列リテラルで作られたかを呼び出すことができるString関数としてなし new例えば、:String(0); //"0", Real string, not an object
Esailija

6
しかし、詳細なケースでは、演算子「==」はまったく同じように動作します。
Yaron Levi

270

この弁護士を追加しましょう:

疑問がある場合は、仕様を読んでください!

ECMA-262は、JavaScriptが方言であるスクリプト言語の仕様です。もちろん実際には、最も重要なブラウザーの動作は、何かの処理方法の難解な定義よりも重要です。しかし、なぜ新しいString( "a")!== "a"なのかを理解しておくと役に立ちます。

この質問を明確にするために、仕様の読み方を説明させてください。この非常に古いトピックでは、非常に奇妙な効果について誰も答えがありませんでした。したがって、仕様を読むことができれば、これはあなたの職業で途方もなく役立ちます。習得したスキルです。続けましょう。

PDFファイルで===を検索すると、仕様の56ページに移動します。Strict Equals演算子(===)で、specicalaleseを調べた後、次のことがわかります。

11.9.6厳密な等値比較アルゴリズム
x === yの比較では、xとyが値であり、trueまたはfalseを生成します。このような比較は次のように実行されます
  。1. Type(x)がType(y)と異なる場合は、falseを返します
  2. Type(x)がUndefinedの場合、trueを返します
  3. Type(x)がNullの場合、trueを返します
  4. Type(x)が数値でない
  場合は、手順11に進みます。5. xがNaNの場合は、falseを返します
  6. yがNaNの場合、falseを返します
  7. xがyと同じ数値の場合、trueを返します
  8. xが+0でyが-0の場合、trueを返します
  9. xが−0でyが+0の場合、trueを返します
  10. falseを返します
  11. Type(x)が文字列の場合、xとyがまったく同じ文字シーケンス(長さが同じで、対応する位置に同じ文字がある)であればtrueを返します。それ以外の場合は、falseを返します
  12. Type(x)がブール値の場合、xとyが両方ともtrueまたは両方ともfalseであればtrueを返します。それ以外の場合は、falseを返します
  13. trueを返すxとyが同じオブジェクトを参照する場合、または互いに結合されたオブジェクトを参照する場合(13.1.2を参照)。それ以外の場合は、falseを返します

興味深いのは、ステップ11です。はい、文字列は値の型として扱われます。しかし、これはnew String( "a")!== "a"である理由を説明していません。ECMA-262に準拠していないブラウザはありますか?

そんなに早くない!

オペランドの型を確認してみましょう。typeof()でそれらをラップすることにより、自分で試してみてください。new String( "a")がオブジェクトであることがわかり、ステップ1が使用されます。タイプが異なる場合はfalseを返します

なぜnew String( "a")が文字列を返さないのか疑問に思うなら、仕様を読んでみるのはいかがですか?楽しんで!


Aidiakapiは以下のコメントでこれを書きました:

仕様から

11.2.2新しいオペレーター

Type(constructor)がObjectでない場合、TypeError例外をスローします。

つまり、StringがObject型でない場合、new演算子では使用できません。

newは、Stringコンストラクタの場合でも、常にObjectを返します。そして悲しいかな!文字列の値セマンティクス(手順11を参照)は失われます。

そして、これは最後に次を意味します:new String( "a")!== "a"


Type(x)の結果はtypeofと同じであることが暗黙的に示されますか?
Dfr

@nalply私はでの動作の不安を正確に理解していません。new String('x')これは、プリミティブラッパーオブジェクトを使用するコードを実際に野生で見たことがないためです。特に、最近はそうする理由はあまりないと思います。実行するコードに遭遇したことがありますか?
アンディ

@Andy問題は悪意があるか、サードパーティのコードがずさんなだけなので、誰もを使用していないとは限りませんnew String()
nalply

ずさんな場合は、===で確認できます。それが悪意のあるものであれば、new String()おそらくあなたの心配は最も少ないと思います。理論的には懸念を理解していますが、ここでも実際の例はありますか?私にとっては、誰かがundefined別の価値観を設定できるという古い不安のようなものです。
アンディ

どこで取得したかわかりませんが、ステップ2で比較アルゴリズムが間違っています。「7.2.15厳密な等価比較」では、最初に型が同じかどうかを確認し、そうであれば、それらが数値かどうかを確認します。そうでない場合、セクション「7.2.12 SameValueNonNumber(x、y)」が使用されます。
Rusty Core

101

PHPとJavaScriptでは、これは厳密な等価演算子です。つまり、タイプと値の両方を比較します。


10
@David:正解です。そのため、この回答は不正確(または間違っている場合もある)です
フィリップレイバート

7
@David var a = {}, b = {}; a == bはfalseを返します。
nyuszika7h

6
はい:同じタイプと値を持つ2つの異なるオブジェクトはfalseを比較します。なぜ50の賛成票があるのですか?
アレクシス2013年

4
一例ではので、私はこれが古い実現が、この答えはまだ「正しい」である理由明らかにすることであるvar a = {}, b = {};、両方の間aとは、b実際にオブジェクトの両方ですが、そうでない同じ技術的に言えば、値。それらは異なるインスタンスです。インスタンスの比較は、プリミティブの比較とは動作が異なることに注意してください。これはおそらくこの混乱を助長します。プリミティブデータ型のインスタンスバージョンを使用すると、同様の比較動作が見られます。例:new String('asdf')またはnew Number(5)。例:new Number(5) == new Number(5)同じ値を保持していてもfalseです。
Norman Breau

1
オブジェクトへの参照は、メモリスロットへのポインタであるため、実際には値の型であることを誰もが忘れます。オブジェクト比較は「オブジェクトの値」を比較するのではなく、両方のポインタが同じかどうかを比較します。つまり、同じメモリスロットを参照することになります。「===演算子は、「型、値、およびメモリ内のオブジェクトへの参照が同じである場合」と実際に言う必要があるため、型の比較では非常に微妙な違いです。
Stokely、2018

101

私は次のようなコードを使用して、Firebugを搭載したFirefoxでこれをテストしました。

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

そして

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

私の結果(各5回テストし、平均した):

==: 115.2
===: 114.4

したがって、ごくわずかな違い(これは10万回以上の反復であることに注意してください)は無視できると言えます。パフォーマンスはそうする理由ではありませ===。型安全性(まあ、JavaScriptで取得するのと同じくらい安全です)とコードの品質です。


3
タイプセーフだけではなく、論理的な正確さを求めます==。反対の場合は、物事を真実にしたいことがあります。
rpjohnst 2011

4
さて、==演算子の実際の型強制がある場合、これらはどのように比較されますか?パフォーマンスが向上するのはそのときです。
Hubert OG

2
タイプの不等式のみをチェックするのがより速いという前述の理由により、適切にテストされた場合の主な違い。jsfiddle.net/4jhuxkb2
Doug Morrow、

型強制を行わないテスト(全体の理由)を使用しながら、console.time()を使用して、このようなパフォーマンスを1秒あたりのオペレーション数で測定します。1つのブラウザー(市場シェアが約5%のテスト)ではありません。遅い)を考慮に入れてください。これは完全に無意味なテストです。あなたはパフォーマンスがそれ===以上に使用する理由ではないのは正しい==ですが、それらのパフォーマンスが本質的に等しいこと、そしてこのテストがそれを証明し、他の多くの人々が私に全く不合理であることを証明すると思うのは間違いです。
スティーブンMアービング

97

JavaScriptでは、同じ値とタイプを意味します。

例えば、

4 == "4" // will return true

だが

4 === "4" // will return false 

87

===演算子は、それが、厳密な比較演算子と呼ばれて異なって==演算子。

2つの変数aとbを取ります。

以下のために「== B」であることを本当のaとbの必要性を評価するために、同じ値

「a === b」の場合、aとbは同じ値で、同じ型でなければなりません trueと評価するにで。

次の例を見てください

var a = 1;
var b = "1";

if (a == b) //evaluates to true as a and b are both 1
{
    alert("a == b");
}

if (a === b) //evaluates to false as a is not the same type as b
{
    alert("a === b");
}

要約すると==演算子を使用したくない場合、===演算子を使用すると、trueと評価される場合があります。演算子方が安全です。

90%の使用シナリオでは、どちらを使用しても問題ありませんが、ある日予期せぬ動作が発生した場合の違いを知っておくと便利です。


82

なぜ==そんなに予測できないのですか?

空の文字列""を数字のゼロと比較すると何がわかり0ますか?

true

うん、==空の文字列と数字のゼロは同じ時間によるとそうです。

そして、それはそこで終わりません、ここに別のものがあります:

'0' == false // true

配列では物事が本当に奇妙になります。

[1] == true // true
[] == false // true
[[]] == false // true
[0] == false // true

次に、文字列で奇妙な

[1,2,3] == '1,2,3' // true - REALLY?!
'\r\n\t' == 0 // true - Come on!

ひどくなる:

いつ等しくないか

let A = ''  // empty string
let B = 0   // zero
let C = '0' // zero string

A == B // true - ok... 
B == C // true - so far so good...
A == C // **FALSE** - Plot twist!

もう一度言いましょう。

(A == B) && (B == C) // true
(A == C) // **FALSE**

そして、これはプリミティブで得られるクレイジーなものです。

==オブジェクトで使用すると、まったく新しいレベルのクレイジーになります。

この時点でおそらくあなたは不思議に思っています...

なぜこれが起こるのですか?

まあそれ===は、2つの値が同じかどうかをチェックするだけの「triple equals」()とは異なります。

==ない他のものの全体の束を

これには、関数の特別な処理、null、未定義の文字列の特別な処理があり、名前を付けます。

それはかなり風変わりです。

実際、何をする関数を書こうとすると、==次のようになります。

function isEqual(x, y) { // if `==` were a function
    if(typeof y === typeof x) return y === x;
    // treat null and undefined the same
    var xIsNothing = (y === undefined) || (y === null);
    var yIsNothing = (x === undefined) || (x === null);

    if(xIsNothing || yIsNothing) return (xIsNothing && yIsNothing);

    if(typeof y === "function" || typeof x === "function") {
        // if either value is a string 
        // convert the function into a string and compare
        if(typeof x === "string") {
            return x === y.toString();
        } else if(typeof y === "string") {
            return x.toString() === y;
        } 
        return false;
    }

    if(typeof x === "object") x = toPrimitive(x);
    if(typeof y === "object") y = toPrimitive(y);
    if(typeof y === typeof x) return y === x;

    // convert x and y into numbers if they are not already use the "+" trick
    if(typeof x !== "number") x = +x;
    if(typeof y !== "number") y = +y;
    // actually the real `==` is even more complicated than this, especially in ES6
    return x === y;
}

function toPrimitive(obj) {
    var value = obj.valueOf();
    if(obj !== value) return value;
    return obj.toString();
}

これはどういう意味ですか?

その意味は ==は複雑だです。

複雑なため、使用するとどうなるかわかりません。

つまり、バグが発生する可能性があります。

だから、物語の教訓は...

あなたの人生をそれほど複雑にしないでください。

===代わりに使用します==

終わり。


あなたlooseEqualは間違っている。Function == Function.toString()は真ですが、looseEqual(Function, Function.toString())偽です。最初に関数を除外する理由がわかりません。
Oriol 2016

@オリオールあなたは正しかった、私はそれを説明するためにコードを更新しました、FYIは私のテストに基づいて「関数」のフィルターを削除するのに十分ではなく、代わりに「関数」は完全に異なって処理されなければなりませんでした。
Luis Perez

仕様では関数の扱いが異なり、単なるオブジェクトであることに注意しください。問題はtypeof x === "object"、それがオブジェクトであるかどうかの確認に依存しているようですが、 `typeofはnull以外のプリミティブに対してのみ機能します。値がオブジェクトであるかどうかを確認する適切な方法の
Oriol

関数とオブジェクトを同じように扱ってみましたが、彼の結果は正しくありませんでした。たとえば、関数がオブジェクトのように扱われた場合、関数を、関数に一致するvalueOf()またはtoString()関数を実装するオブジェクトと比較すると成功しますが、実際には成功しません。例:(function blah() { console.log("test"); }) != {valueOf:function(){return "function blah() { console.log(\"test\"); }";}}-すべてのテストを実行するこのJS Fiddleを確認してください:jsfiddle.net/luisperezphd/7k6gcn6g(1,225のテスト順列があります)
Luis Perez

1
そうです、すばらしい観察です。これ==は、多くのことを実行して結果を予測することを非常に困難にする主要なポイントを強調します===が、はるかに簡単で予測可能であること===は、推奨される主な理由の1つです。(私はあなたのポイントを言及する回答にメモを追加します)
Luis Perez

81

===同じ辺のが等しいことを確認します


例:

'1' === 1 // will return "false" because `string` is not a `number`

一般的な例:

0 == ''  // will be "true", but it's very common to want this check to be "false"

別の一般的な例:

null == undefined // returns "true", but in most cases a distinction is necessary

何度も型指定されていない値がいずれかの場合は、あなたが気にしないので、チェックは便利だろうundefinednull0 または""


7
また、'string' !== 'number'
Homer

72

厳密な等価性/比較「===」のJavaScript実行フロー図

JavaScriptの厳密な等価性

厳密でない等価性/比較 '=='のJavaScript実行フロー図

JavaScriptが等しくない


string矢印が大きな灰色のボックスを指している理由がわかりません。これは、インタラプタが文字列を数値にキャストしていることを意味しているのですか?
vsync 2017

@vsync灰色のボックス内の文字列オプションを指します。つまり、文字列->#|| NaN。Javascriptはタイプスクリプト言語ではありません。つまり、基本的には任意のタイプの変数を持つことができます。だから、それはその灰色のボックスを指しています。
Samar Panda

stringはtypeと比較されることになっているので、キャストの目的であるかどうかを単に尋ねただけですnumber。したがって、インタラプタは文字列を比較する対象を調べ、それに応じて文字列をキャストしますか?
vsync

1
大きな灰色のボックスはToNumber、さまざまなタイプが指定された場合に返されるものであるため、文字列が指定された場合、最後のオプションのみを選択します(そしてそれを数値に変換します)。==用途ToNumberの場合にのみstring == number、またはboolean == anything(のみで上記のstring/ boolean)。この手段は、==変換することはありませんundefinednull、彼らは灰色のボックスにあるにもかかわらず。(いずれundefinednullまたは両方の任意の組み合わせの場合、==は常にを返しtrueます。また、値が左側にあるか右側にあるかは関係ありません==(および===)は同じ結果を返します。)
user2033427

55

JavaScriptの=== ==

0==false   // true
0===false  // false, because they are of a different type
1=="1"     // true, auto type coercion
1==="1"    // false, because they are of a different type

54

これは、型強制なしの等価性を 意味します型強制は、JavaScriptが他のデータ型を文字列データ型に自動的に変換しないことを意味します

0==false   // true,although they are different types

0===false  // false,as they are different types

2=='2'    //true,different types,one is string and another is integer but 
            javaScript convert 2 to string by using == operator 

2==='2'  //false because by using === operator ,javaScript do not convert 
           integer to string 

2===2   //true because both have same value and same types 

48

典型的なスクリプトでは、パフォーマンスの違いはありません。より重要なのは、千の "==="が千の "=="より1 KB重いという事実かもしれません:) JavaScriptプロファイラーは、ケースにパフォーマンスの違いがあるかどうかを教えてくれます。

しかし、個人的にはJSLintが提案することを行います。この推奨事項は、パフォーマンスの問題のためではなく、型の強制('\t\r\n' == 0)が真であるためです。


4
常に正しいとは限りません。gzip圧縮では、その違いはほとんど無視できます。
ダニエルXムーア

1
同意しますが、「===」が1000の場合、コード行が1万行になることも意味するので、1kb程度です...;)
Jonny

サイズに関心がある場合は、すべての==を===に交換し、av evalにラップされた正規表現を使用して元に戻します

46

等価比較演算子==は混乱を招くため、回避する必要があります。

あなたがいる場合する必要があり、それと一緒に暮らす、次の3つの事を覚えています:

  1. それは推移ではありません:(== b)は、および(B == C)につながらない(A == C)
  2. (a == b)(a!= b)は常に反対のブール値を保持し、すべてのaとbを否定します。
  3. 疑問がある場合は、次の真理値表を暗記してください。

JAVASCRIPTの等価演算子真理値表

  • テーブルの各行は、3つの相互に「等しい」値のセットです。つまり、等号==記号を使用して、2つの値が等しいことを意味します*

** STRANGE:最初の列の2つの値はその意味で等しくないことに注意してください。**

''       == 0 == false   // Any two values among these 3 ones are equal with the == operator
'0'      == 0 == false   // Also a set of 3 equal values, note that only 0 and false are repeated
'\t'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\r'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\n'     == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
'\t\r\n' == 0 == false   // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

null == undefined  // These two "default" values are not-equal to any of the listed values above
NaN                // NaN is not equal to any thing, even to itself.

39

使用方法の2つの操作の間にパフォーマンスの違いはほとんどありません。両方のパラメーターが既に同じ型であるため、実行する型変換はありません。両方の操作には、型比較とそれに続く値比較があります。


38

はい!それは問題である。

===JavaScriptの演算子は値と型をチェックしますが、as ==演算子は値をチェックするだけです(必要に応じて型変換を行います)

ここに画像の説明を入力してください

簡単にテストできます。次のコードをHTMLファイルに貼り付けて、ブラウザで開きます

<script>

function onPageLoad()
{
    var x = "5";
    var y = 5;
    alert(x === 5);
};

</script>

</head>

<body onload='onPageLoad();'>

警告では「false」が表示されます。次に、onPageLoad()メソッドを変更してtruealert(x == 5);を取得します


33

=== 演算子は、値と変数の型が等しいかどうかをチェックします。

== 演算子は、変数の値が等しいかどうかをチェックするだけです。


32

厳密なチェックテストです。

0とfalseとnullの間でチェックしている場合は特に良いことです。

たとえば、次の場合:

$a = 0;

次に:

$a==0; 
$a==NULL;
$a==false;

すべてがtrueを返すため、これは必要ない場合があります。配列の0番目のインデックスを返すか、失敗した場合にfalseを返す関数があるとします。「== false」でチェックすると、混乱する結果になる可能性があります。

上記と同じですが、厳密なテストです:

$a = 0;

$a===0; // returns true
$a===NULL; // returns false
$a===false; // returns false

3
JavaScriptでは、これは完全に間違っており、誤って不完全です。0 != null。-1
Ry-

31

JSLintは時々、変更する非現実的な理由を提供します。===とまったく同じパフォーマンスを持っています==タイプがすでに同じである場合います。

タイプが同じでない場合にのみ高速になります。その場合、タイプを変換しようとせず、直接falseを返します。

したがって、私見、 JSLintは新しいコードの記述に使用される可能性がありますが、無駄な過剰最適化は絶対に避けなければなりません。

つまり、aは文字列のみであるという事実を知っているときのように、チェックで変更==する必要はありません。===if (a == 'test')

このように多くのコードを変更すると、開発者とレビュー担当者の時間が無駄になり、何も達成されません。


30

単に

==手段の比較オペランド間 type conversion

===なしのオペランド間の比較を意味します type conversion

javaScriptの型変換とは、javaScriptが他のデータ型を文字列データ型に自動的に変換することを意味します。

例えば:

123=='123'   //will return true, because JS convert integer 123 to string '123'
             //as we used '==' operator 

123==='123' //will return false, because JS do not convert integer 123 to string 
            //'123' as we used '===' operator 

26

簡単な例は

2 == '2'  -> true, values are SAME because of type conversion.

2 === '2'  -> false, values are NOT SAME because of no type conversion.

25

上位2つの回答は、上記の==は平等を意味し、===は同一性を意味します。残念ながら、このステートメントは正しくありません。

==の両方のオペランドがオブジェクトである場合、それらは比較され、同じオブジェクトであるかどうかが確認されます。両方のオペランドが同じオブジェクトを指している場合、等号演算子はtrueを返します。そうでない場合、2つは等しくありません。

var a = [1, 2, 3];  
var b = [1, 2, 3];  
console.log(a == b)  // false  
console.log(a === b) // false  

上記のコードでは、aとbが同じオブジェクトではないため、==と===の両方がfalseになります。

つまり、==の両方のオペランドがオブジェクトである場合、==は===と同じように動作し、これは同一性も意味します。この2つの演算子の本質的な違いは、型変換についてです。==は等価性をチェックする前に変換を行いますが、===は行いません。


24

経験則として、私は===代わりに==(そして!==代わりに!=)を使用します。

理由は上記の回答で説明されており、Douglas Crockfordもそれについてはかなり明確です(JavaScript:The Good Parts)。

しかし、そこにある1つの例外は== null「nullまたは未定義である」かどうかを確認するための効率的な方法は次のとおりです。

if( value == null ){
    // value is either null or undefined
}

たとえば、jQuery 1.9.1はこのパターンを43回使用し、JSHint構文チェッカーeqnullはこの理由でリラックスオプションも提供しています。

jQueryのスタイルガイド

厳密な等価チェック(===)は、==を優先して使用する必要があります。唯一の例外は、未定義およびnullを介してnullをチェックする場合です。

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

22

問題は、JavaScriptには多くの暗黙的な変換の意味があるため、簡単に問題が発生する可能性があるということです...

var x = 0;
var isTrue = x == null;
var isFalse = x === null;

これはすぐに問題になります。暗黙の変換が「悪」である理由の最良のサンプルは、MFC / C ++のこのコードから取得できます。これは、CStringからポインターのtypedef型であるHANDLEへの暗黙の変換により実際にコンパイルされます...

CString x;
delete x;

これは明らかに実行時に非常に未定義のことをします...

GoogleはC ++およびSTLで暗黙の変換を行い、それに対するいくつかの引数を取得します...


2
0 == nullは偽です。
Garrett


21

同等性の比較:

オペレーター ==

両方のオペランドが等しい場合、trueを返します。オペランドは比較される前に同じ型に変換されます。

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

等価性と型の比較:

オペレーター ===

両方のオペランドが等しく、同じ型の場合、trueを返します。この方法で比較すると、通常、裏側の型変換がないため、より適切で安全です。

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


20

nullおよびundefinedは無意味です。つまり、

var a;
var b = null;

ここに値はaありbません。一方、0、false、 ''はすべて値です。これらすべての間で共通することの1つは、これらがすべて偽の値であること、つまり、すべて偽の条件を満たすことです。

したがって、0、false、および ''は一緒にサブグループを形成します。一方、null&undefinedは2番目のサブグループを形成します。下の画像で比較を確認してください。nullとundefinedは等しくなります。他の3つは互いに等しくなります。しかし、それらはすべてJavaScriptでは偽の条件として扱われます。

ここに画像の説明を入力してください

これは他のオブジェクト({}、配列など)と同じです。空でない文字列とブール値trueはすべて真の条件です。しかし、それらはすべて同じではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.