JavaScriptの闇という言葉を聞いたことがあるでしょうか。
JavaScriptは一部書き方を他のPython等の言語と同じように書いてしまうと後で致命的なバグの原因になることがあります。
そんなJavaScriptの闇の一例を紹介します。
varの欠陥
JavaScriptは変数を宣言する時にvarかletを使用します。
var hoge = "hoge";
let hoge = "hoge";
2015年以前はverしか選択肢がありませんでした。そんなvarにはかなりの欠陥があります。
以下のようなコードがあったとします。
var greeting = "Hello";
if(true){
var greeting = "Bye";
}
console.log(greeting);
この時、コンソールに表示される文字列は「Hello」でなければいけません。
それは、if文内で宣言されている変数は、そのif文内でしか参照できないよう、変数のスコープが発生するからです。
しかし、これを実際に実行してみると、コンソールには「Bye」が表示されてしまいます。
これにより、グローバル変数であるgreetingがif文内の変数であるgreetingに上書きされてしまいます。
変数を宣言する場合はletを用いましょう。
型の自動変換
JavaScriptもPython等と同様に型を自動で決めます。
以下のようなコードがあります。
console.log(1+1);
console.log("1+1");
console.log("1"+1);
console.log("1"-1);
この時コンソールにはどう表示されるでしょうか。
本来ならエラーが発生します。1つずつ見ると以下のようになるはずです。
2
1+1
error
error
ですが、JavaScriptでは
2
1+1
11
0
となります。
console.log("1"+1);
これの"1"は文字列で、1は数字のはずです。しかし、自動で型変換が行われることで、
両方文字列になります。結果("1"+"1")となり、11と表示されます。
console.log("1"-1);
こっちの場合は逆で、型変換によって文字列だったはずの"1"が数字の1になります。
結果(1-1)となり、0と表示されます。
等価演算子
一般的な言語の等価演算子は==です。
JavaScriptには等価演算子が2つあり、片方が==
もう片方が===で、こっちは正確には厳密等価演算子と呼ばれます。
以下のようなコードがあったとします。
console.log(true);
console.log(0 == 0);
console.log(1 > 0);
これらはすべてコンソールにはtrueと表示されます。
以下の場合も考えてみましょう
console.log(0 == "0");
console.log(1 == true);
console.log("1" == true);
これでもtrueになってしまいます。
両辺で型が異なるのにtrueとなります。
そこで厳密等価演算子を使用すると
console.log(0 === "0");
console.log(1 === true);
console.log("1" === true);
すべてfalseになります。
等価演算子を用いる時は厳密等価演算子を使用しましょう。
文字列と数字など、型の違うもの同士を比較し、trueと表示させたいのなら、
以下のようにキャストを行いましょう。
console.log(Strint(1) === "1");
console.log(1 === Number("1"));
以上JavaScriptの闇の一例でした。