いつも何も考えずに**==を使ってしまいがちですが、僕がずっと使っているIDE NetBeansでは、===**を使えと警告してくれます。
この違いって何でしょうか?
#==と===の違い
まず、文字と数値の比較実験
var a = "1";
var b = 1;
console.log(a==b);
結果:true
console.log(a===b);
結果:false
それぞれの演算子についてここで調べてみると、それぞれ機能が違うことがわかります。
##== 等価演算子
数値と文字列を比較するとき、文字列は数値に変換されます。JavaScript は文字列の数値リテラルを Number 型の数値に変換しようと試みます。最初に、その文字列の数値リテラルから数学的な値を引き出します。次に、最も近い Number 型の値にこの値を丸めます。
つまり**==**は、文字列と数値の比較の場合、文字列を数値に変換してくれるわけです。
##=== 厳密等価演算子
オペランド同士が、型を変換することなく(上に示した通り)厳密に等しいならば真を返します。
この場合、文字列は数値にに変換されないので、falseが返るわけです。
#型変換について
等価演算子==では型変換が行われる場合があると説明しました。
型ていってもいろいろあるけど、どんな風に変換されるんでしょうか?
##Boolean型
もしオペランドの片方が Boolean ならば、その論理オペランドは true ならば 1 に、そして false ならば +0 に変換されます。
console.log(true==1); // true
console.log(true===1); // false
console.log(false== 0); // true
console.log(false=== 0); //false
##オブジェクト
オブジェクトを数値または文字列と比較する場合、JavaScript はそのオブジェクトの既定値を返そうとします。演算子はそのオブジェクトを、そのオブジェクトの valueOf や toString といったメソッドを用いて、プリミティブな値か、String か、あるいは Number の値に変換しようとします。そうした変換の試みが失敗したときにはランタイムエラーが生成されます。
console.log("foo" == new String("foo")); //true
console.log("foo" === new String("foo")); //false
上記は、プリミティブ型と、String型の比較であるため、String型がプリミティブに型変換してくれたわけです。
従って、下記はfalseです。
console.log(new String("foo")==new String("foo"));
異なるオブジェクト(というよりインスタンス)同士の比較になるため、falseになります。
ところで、こんないたずらするとどうなるか
var s = new String("foo");
console.log("foo"==s);//結果:true
//valueOfメソッドを書き換え
s.valueOf=function(){return "boo";}
console.log("foo"==s); //結果:false
console.log("boo"==s); //結果:true
String型とプリミティブ型の文字列を比較した場合、確かにvalueOfが呼ばれて、文字列と比較していることがわかります。
あと、undefinedとnullの比較をするとこうなります。
console.log(null == undefined);
結果:true
console.log(null === undefined);
結果:false
#終わり
うまくまとめられないけど、名前の通り、
**===**のほうが厳密に比較してくれるってことです。