javascriptで何らかの値を比較する場合、たとえばif文などで分岐させる場合の条件比較に気を付けるべきことを説明したいと思います。
変数の型について
まず前提の話から。以下の簡単なコードを見てほしいです。
var a;
var b = 1;
var c = "文字列";
var d = true;
var e = {obj:objdata};
var f = null;
変数宣言した場合に何も値を代入しないと、その変数はundefined
(未定義)を持つことになります。 上記のコードでは変数a
は宣言だけを行い、何も代入していないのでundefined
となります。これはundefined型とよばれる型となります。
b
は数字を代入しているので数字型(Number型などとも)となります。(数字型は数字以外にNaN
という値を取る場合があります。これはNot A Number
と呼ばれる値で計算結果などが数字に変換できない場合などに現れます。 )
c
は文字を代入しているので文字列型。
d
は真偽値型でtrue
(真)かfalse
(偽)のどちらかになります。(var d = “true”; としてしまうと文字列型になる)
e
はオブジェクトを代入しているのでオブジェクト型。 javascriptでは関数もオブジェクト扱いなので、変数に関数を代入した場合はオブジェクト型になります。
最後のf
は計算が間違った際などに代入されるnull型です。
このようにjavascriptは内部で型を持っていますが、変数宣言時には型宣言は行わないです。代入された値で自動的に型が決まることになります。
型変換
型変換というのは、違う型同士を比較、計算する場合に型を合わせる(変換する)ことを指す。
どのように変換するかは言語の仕様によって変わるので、統一されてはいないです。javascriptでも定められたルールに従い型変換が行われています。
以下に型変換の簡単な実例を挙げたいです。
通常「文字列と数字を足す」ということはできないですが、型変換が行われることによって計算が可能になります。
var a = "1234";
var b = 1234;
//例1
var c = a + b;
console.log(c); //12341234と表示
console.log(typeof(c)); //stringと表示
//例2
var d = a - b;
console.log(d); //0と表示
console.log(typeof(d)); //numberと表示
上記のコードではa
は文字列、b
は数字型で宣言しています。typeof
は型を調べる演算子です。
例1は計算の結果は12341234
となり、型はstring
(文字列)となりました。これは数字型のb
が型変換され文字列型として計算されたことを示す。
逆に例2は計算の結果は0
となり、型はnumber
(数字型)となりました。今度は文字列型のa
が型変換され数字型として計算されたことを示します。
このように型が違う場合は型変換が行われることになります。
比較演算子の挙動
とても重要なことだが「比較演算子==」は比較する同士で型が合っていない場合、型変換を行おうとします。
その為、以下の例で言えばa
はundefined
となりますが、ture
と比較できるように型変換が行われることになります。
//比較演算子
var a;
var b=1;
console.log(a+ " " +b);//undefined 1と表示されるはず
if(a == true){
console.log("変数aが選択されました");
}else if(b == true){
console.log("変数bが選択されました");//これが表示されるはず
}else{
console.log("型が違うか、定義されていないか、0、NaN、null、空文字です");
}
ture
は真偽値リテラルのture
ということになります。型としては真偽値型。tureという文字列ではないことに注意していただきたいです。
javascriptでは真偽値型への型変換の場合、undefined、null、0、空文字列、NaN
はfalse
に変換されるようになっています。
上記のコード例ではa
のundefined
は真偽値型へ変換されます。 型変換の結果undefined
はfalse
に変換されます。 結果的にfalse==ture
という意味になり、(a == true)
は偽となります。
bは上記で述べたとおりnull、0、空文字列、NaN
ではないので、ture
と評価されます。 結果的にture==ture
となり、(b == true)
は真となります。
厳密比較演算子の挙動
しかし厳密比較演算子を使用すると結果が異なります。「厳密比較演算子===」は型が合っているかどうかまで評価します。
//厳密比較演算子
var a;
var b=1;
console.log(a+ " " +b);//undefined 1と表示されるはず
if(a === true){
console.log("変数aが選択されました");
}else if(b === true){
console.log("変数bが選択されました");
}else{
console.log("型が違うか、定義されていないか0、null、空文字、NaNです");//これが表示されるはず
}
「厳密比較演算子===」では型変換を行わなわず、型自体が合っているのかまで比較します。 その為、(a === true)
は(undefined===ture)
と言う意味になります。型も違うし値も違うので偽となります。
(b === true)
も同様で、(1 === true)
という意味になり偽となります。どちらとも偽になるので最後のelse部分が実行されるという訳です。
なにかを比較する時、演算子の使い方で結果が変わってくるという実例です。
まとめ
通常はより厳密な「厳密比較演算子===」を使う機会が多いと思います。しかし、ロジックによっては型変換を行う「比較演算子==」が便利な場合があります。
いずれにしても、比較演算では比較対象の型の在り様で、比較結果が変わる可能性があると言うことを注意したいです。