JavaScript 忘れがちな === と == の違い

  • 110
    Like
  • 1
    Comment
More than 1 year has passed since last update.

いつも何も考えずに==を使ってしまいがちですが、僕がずっと使っている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

終わり

うまくまとめられないけど、名前の通り、
===のほうが厳密に比較してくれるってことです。