事の発端
ある日私はJavaScriptの歴史について少し学びました。
その中で、ES6(ECMAScript2015)でletとconstが追加され、varが非推奨になったことを知りました。
また、ある時には友人からvarは使うんじゃないと言われました。
そこで私は思いました。
「なんでvarなんて存在するの!?varっていらない子じゃない!?」 と。
しかし、存在するからには何か理由があるのだろうと私はvarについて少し調べてみることにしました。
JavaScriptにおけるvar
varはletやconstのようなJavaScriptには変数を宣言するためのキーワードです。
このvar, let, constのは以下の表に示すような違いがあります。
var | let | const | |
---|---|---|---|
再代入 | 可能 | 可能 | 不可能 |
再宣言 | 可能 | 不可能 | 不可能 |
スコープ | 関数スコープ | ブロックスコープ | ブロックスコープ |
巻き上げ | 起こる | 起こらない | 起こらない |
なぜJavaScriptを書く上でvarは嫌われているのか
上の表で示されているようにvarは再宣言が可能という特徴があります。
再宣言が可能なことで、気づかないうちに二重で宣言してしまい予期しない不具合が発生する危険性を孕んでいます。
例えば、以下のような訳のわからないことが発生します。
var num = 1;
console.log(num); // -> 1
if(num === 1) {
var num = 1234;
console.log(num); // -> 1234
}
console.log(num); // -> 1234
-
var
を使用し、num
という変数を宣言 - if 文の中で
var
を使用し、num
という変数を宣言している。let
やconst
であればブロックスコープの中で宣言したという扱いになり変数名は衝突しないが、var
にはブロックスコープがないため、変数名が衝突。再宣言が起きて1行目のnum
の中身が書き換わってしまう -
num
が 1234 になる
このようなことが発生するため、varは嫌われES6以降は使わないようにしましょうと言われているようです。
JavaScript以外のプログラミング言語におけるvar
調べてみるとvarはJavaScript以外でも使われている言語があるようです。
しかし、どうやら仕様がそれぞれ異なるようです。
JavaやC#,D言語
これらの言語でのvarは暗黙的に型を推論するために使用されるものです。
再宣言はできません。
変数の型が右辺から明らかな場合や型名が長い場合にvarを使うことでコードを読みやすくします。
例えば、以下のような場合です。
// 従来の書き方
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
// varを使った書き方
var dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
Scala
Scalaには変数が再代入できるvarと再代入できないvalの2種類の変数があります。
再宣言はできません。
なぜJavaScriptではvarが存在するのか
この部分に関してはあまり有用な記事を発見できず、自分の推測・妄想で書いているので詳しい先輩エンジニアの方がいらっしゃいましたら教えていただけると幸いです。
なぜ開発当初にこの仕様のvarを実装し、他の変数を用意しなかったのか
JavaScriptは1995年にわずか10日間で開発されたようです。
そのため、実装しやすくするために再代入も可能なvarを実装したのかもしれないです。
なぜ今もJavaScriptにvarは残っているのか
ES6以前に実装されたサイトやES6以降も慣れたvarで書いている人もいるため、varを消してしまうと様々なサイトで不具合が発生されると考えられるためだと私は考えます。
さいごに
- JavaScriptにおいてvarは再宣言が可能な変数で、letやconstが存在する現在(ES6以降)では時代に置き去りにされた要らない子のようです。
- JavaScript以外では現役のようです。