論理演算子 演算子(== vs===)と等しいJavaScriptは、JavaScriptの比較で使用する必要がありますか?




javascript=== 否定 (24)

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

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

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

<script>

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

</script>

</head>

<body onload='onPageLoad();'>

あなたは警告で「 」を得るでしょう。 onPageLoad()メソッドを変更してalert(x == 5); あなたは本当になるでしょう。

私はJSLintを使ってJavaScriptを使っていますが、 idSele_UNVEHtype.value.length == 0idSele_UNVEHtype.value.length == 0内で比較するようなことをするとき== (2つの等号)を===ステートメント。

====に置き換えるとパフォーマンス上のメリットはありますか?

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

タイプ変換が行われない場合は、 ==以上のパフォーマンスが得られますか?


JSLintは時々あなたに物を修正する非現実的な理由を与えます。 ===すでに型が同じであれば==と全く同じ性能を持ちます。

型が同じでない場合にのみ、より速くなります。この場合、型の変換は試みませんが、直接falseを返します。

だから、IMHO JSLintは新しいコードを書くのに使われるかもしれませんが、無駄なオーバーオプティマイゼーションは避けてください。

意味は、 == to ===if (a == 'test')ようなチェックで変更する理由はありません。

開発者や批評家の時間を無駄にし、何も達成しないように多くのコードを修正する


nullとundefinedは無駄です。つまり、

var a;
var b = null;

ここには値がaありbません。一方、0、偽、および 'はすべて値です。これら全てに共通しているのは、すべてが虚偽の値であるということです。つまり、すべて虚偽の条件を満たすことを意味します。

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

これは、任意のオブジェクト({}や配列など)と同じですが、空でない文字列&Boolean trueは真実の条件です。しかし、彼らはすべて平等ではありません。


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


これは、型強制変換なしでの等価性を意味します。型変換は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 

上の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つの演算子の本質的な違いは型変換です。==は等価をチェックする前に変換を行いますが、===は変換しません。


同一性( === )演算子は、型変換が行われないことを除いて、等価( == )演算子と同じように動作し、型は同じであるとみなされる必要があります。

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

==演算子は、必要な型変換を行った後 、等価性を比較します。 ===演算子は変換を行わないので、2つの値が同じ型でない場合、 ===は単にfalse返しfalse 。 両方とも同等に速いです。

Douglas Crockfordの優れたJavaScript:The Good Parts

JavaScriptには、 ===!== 2つの等価演算子と、悪い双子==!= 2つのセットがあり!= 。 良いものは、あなたが期待する方法で動作します。 2つのオペランドが同じ型で同じ値を持つ場合、 ===trueを生成し、 !==false生成し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を生成しfalse

更新:

コメントの中の@Casebashと参照型に関する@Phillipe Laybaertの answerが良い点でした。 参照型=====に対しては、(特殊な場合を除いて)互いに一貫して動作します。

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を返しtrueが、 ===はそれらが同じ型ではなく、 falseを返すことを見ています。 どちらが正しいですか? それは本当にあなたが比較しようとしているものに依存します。 私のアドバイスは、質問を完全に回避し、文字列オブジェクトを作成するためにStringコンストラクタを使用しないことです。

参照
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


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

理由は上記の答えで説明されていますし、Douglas Crockfordもかなり明確です(JavaScript:The Good Parts)。

しかし、1つの例外があります== null'nullまたはundefined'をチェックする効率的な方法です:

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;

* 演算子=== vs == *

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

JavaScript === vs ==

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

簡単な例は

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

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

==演算子の使用( 等価

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

===演算子( アイデンティティ )を使用する

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

これは、 等価演算子==が型変換を実行するためです。つまり、インタプリタは暗黙的に値を変換してから比較することを意味します。

一方、 アイデンティティ演算子===は型強制を行わないため、比較の際に値を変換しません。


問題は、JavaScriptが暗黙の変換の意味をたくさん持っているので、簡単に困ってしまうかもしれないということです。

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

かなりすぐに問題になります。なぜ暗黙の変換が "悪い"の最良のサンプルは、CStringからHANDLEへの暗黙的な変換のために実際にコンパイルされるMFC / C ++のこのコードから取り出すことができます。これは、ポインタのtypedef型です...

CString x;
delete x;

明らかにランタイム中に非常に未定義のものはありますか?

C + +とSTL暗黙的な変換のためのGoogle は、それに対していくつかの議論を得る...



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

しかし、個人的に私はJSLintが示唆していることをします。 この推奨は、パフォーマンス上の理由からではなく、タイプ強制変換('\t\r\n' == 0)が真であるためです。


=====間の等価比較の興味深い図解表現。

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

var1 === var2

JavaScriptの等価性テストに===を使用すると、すべてがそのままです。 評価される前に変換されるものはありません。

var1 == var2

JavaScriptの等価性テストに==を使用すると、いくつかの面白い変換が行われます。

この話の教訓:

あなたが==で起こる変換を完全に理解しない限り、 ===使用してください。


平等比較:

オペレーター ==

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

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

平等と型の比較:

オペレーター ===

両方のオペランドが等しく、同じ型の場合に真を返します。あなたがこのように比較すれば、一般的にはより良く安全になります。なぜなら、背後でタイプの変換がないからです。

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

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

だから、次のコードを見てみましょう:

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は、 abが同じ値を持ち、同じ型である場合にtrueを返します

参照型の場合:
a === bは、 abがまったく同じオブジェクトを参照する場合はtrueを返します

文字列の場合:
a === bは、 abが両方とも文字列であり、完全に同じ文字を含む場合は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は同じタイプではありません。 aObject型、 bstring型です。 Stringコンストラクタを使用してString列オブジェクトを作成すると、 ほとんどの場合文字列として動作するObject型のものが作成されます。


等しい比較演算子==は混乱するので、避けるべきです。

あなたがそれに住んでいなければならない場合は、次の3つのことを覚えておいてください:

  1. 推移的ではない: (a == 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.

私は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

だから私は、(これは100000回以上の覚えている)微妙な違いはごくわずかであると言いたい。 パフォーマンスはそれを行う理由ではありません 。 型の安全性(JavaScriptで手に入るほど安全です)、コードの品質は、


2つの操作のパフォーマンスの違いはほとんどありません。 両方のパラメータがすでに同じ型であるため、実行する型変換はありません。 どちらの演算も、型比較の後に値の比較を行います。


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

不確かな場合は、 specification読みください!

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

この質問を明確にするために仕様を読む方法を説明してください。 私はこの非常に古い話題の中で、誰も非常に奇妙な効果の答えを持っていなかったことを知っています。 したがって、仕様を読むことができれば、これはあなたの職業であなたを大いに助けるでしょう。 獲得したスキルです。 それでは、続けましょう。

===についてPDFファイルを検索すると、仕様の56ページに移動します11.9.4。 Strict Equals Operator(===) 、そして私が見つけた仕様書を辿った後:

11.9.6厳密な等価比較アルゴリズム
比較x === y(xとyは値)は、 または偽を生成します 。 このような比較は以下のように行われる。
1. Type(x)がType(y)と異なる場合はfalseを返します
2. Type(x)が未定義の場合はtrueを返します
3. Type(x)がNullの場合はtrueを返します
4. Type(x)がNumberでない場合は、手順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)がStringの場合、xとyがまったく同じ文字列(対応する位置の同じ長さと同じ文字)の場合はtrueを返します 。 それ以外の場合はfalseを返します
12. Type(x)がBooleanである場合、xとyの両方がtrueまたは両方ともfalseの 場合trueを返します 。 それ以外の場合はfalseを返します
13. xとyが同じオブジェクトを参照している場合、または互いに結合しているオブジェクトを参照している場合はtrueを返します (13.1.2参照)。 それ以外の場合はfalseを返します

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

そんなに早くない!

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

なぜ新しいString( "a")が文字列を返さないのか不思議なら、仕様書を読むエクササイズはどうですか? 楽しむ!

Aidiakapiは以下のコメントにこれを書いた:

仕様から

11.2.2新しいオペレータ

Type(コンストラクタ)がObjectでない場合は、TypeError例外をスローします。

言い換えれば、StringがObject型でない場合、それはnew演算子で使用できませんでした。

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

これはついに、 新しい文字列( "a")!== "a"を意味します。


なぜ==は予測できないのですか?

空の文字列""と数字の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つの値が同じかどうかをチェックする「トリプル・イコール」( === )とは異なります。

== 他のものがたくさんあります。

それは関数の特別な処理、ヌルの特別な処理、未定義の文字列、あなたは名前を付けます。

それはかなり変なことになる。

実際に、あなたが何をするかを行う関数を書こうとすると、これは次のようになります:

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();
}

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

それは==が複雑であることを意味します。

複雑なので、使用するときに何が起こるのかを知ることは難しいです。

つまり、あなたはバグに終わる可能性があります。

その話の道徳は、

あなたの人生をより複雑にする。

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

終わり。


同じ辺のが同じであるかどうかをチェックします

例:

'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




identity-operator