2015年5月15日金曜日

変数宣言varの謎にせまる。

JavaScriptについて勉強し始めて間もないですが、様々なサイトや書籍を参考にしながら勉強しています。しかし初心者向けの本や、ドットインストールはとっつきやすさ重視なのか詳細な説明を省いている部分が多いのだと最近気が付きました。

そしてちょうど今クロージャと言うものを調べている時に、プログラミングの基本中の基本、変数宣言について疑問を持ちました・・・。

自分が調べて知ったことを、メモがてらまとめていきます。



  varとは何なのか?


 「var」とはJavaScriptにおける変数の宣言です。C言語ではintやfloatなどが変数宣言になるようです。

変数というのは手元にある本によると、パソコンでよく利用する「名前をつけて保存」のようなものとかいてあります。特定の動作や値に名前をつけておくといった感じです。

C言語では、変数に入れるものが「文字列」だったらchar、「数字」だったらintやfloatなど変数宣言を使い分けないといけないようです。

しかしJavaScriptでは入れたいものが「数字」や「文字列」、「配列」だったり果てには「関数」であってもvarでオッケーという初心者には非常にありがたい仕様です。しかしこれが後々罠になったりします・・・。

var okazu = "レバニラ";
var pi = 3.141592;
var aisatsu = function () { alert("やっはろー"); }

例えばこのような感じですね。一番上は文字列、二番目は数値、三番目は関数が入っています。序盤に書いたように、まさに「名前をつけて保存」のような動作をします。


変数名の付け方


変数名は自由に付けられますが、ある程度のルールがあったりするようです。

まず一つ目に変数名の始まりは「英字」、「_」、「$」でなければいけません。

//使える変数名
var hello;
var _hello;
var $hello;
var Hello;
var $12345;

//使ってはダメな変数名
var 1ji30hun;
var ハロー;

このように数字で始まったり、ひらがなカタカナ漢字はダメなようです。

2つ目のルールは予約語は使えないというものです。
予約語 - JavaScript | MDN
予約語は暗記するしか無いですが、例えばvarなんかも当然予約語なので、

var var = "変数!!!";

のようなことはできません・・・。

また、変数名は個人のセンスによってつけ方が違うと思いますが、ローマ字よりも英語を使ったほうが良いと言われています。

var aisatsu = "こんにちは";
var aisatu = "おはよー";
var greet = "Hello";

こんな感じでローマ字では「つ」の表記方法に「tsu」や「tu」の2通りあったりするので、英語のほうが良いと言われています。しかし英語でも現在形や過去形、複数形などもあるので個人的にはそれもどうなのか・・・と思ったりします。

また、複数の単語をつなげた変数名を付けたいときは、「キャメルシンタックス」を利用すると良いと手元にある本に書いてあります。
var mac_book_pro;
var mac-book-pro;

//これがキャメルシンタックス!
var macBookPro;

単語ごとに何かで区切ろうとすると、人によってはハイフン(-)を使ったりアンダーバー(_)を使う場合があります。さらに区切りの文字の分だけ文字数が増える欠点があります。

キャメルシンタックスは一文字目は小文字で、二単語目以降の一文字目は大文字にする書式です。こうすることで文字数を減らし、表記を統一しやすくなります。

しかしJavaScriptの仕様として大文字小文字を区別するというものがあるので、しっかり英単語を知らないと単語の区切りを間違えるリスクもあります・・・。

変数の使い方


var aisatsu = "おはやっぷー";
alert(aisatsu);//「おはやっぷー」と表示される

aisatsu = "やっはろー";
alert(aisatsu);//「やっはろー」と表示される

先ほど変数名にローマ字は使うべきではないと書きましたが、英語では馴染みづらいのでわざとローマ字で書いています。

変数は1度宣言すれば2回目からは宣言を省いて良いらしいです。ということでこのように変数の中身をもう一度宣言し直すと、「上書き保存」されます。

これが非常に便利で、例えばif文などと合わせて、変数aisatsuの中身を朝なら「おはようございます」、夜なら「こんばんは」とすれば時間に合わせてメッセージを変えることが簡単に行えるようになります。

他にも便利な使い方がありますが、それは他の事柄についてもっと学ぶ必要があります・・・。

varで同じ変数を何度も宣言するとどうなるのか?


上の項目で変数は一度宣言すれば、宣言を省いて良いとかきました。しかし逆に何度も変数を宣言するとどうなるのかという疑問が湧いてきます。

var aisatsu = "おはよう";
alert(aisatsu);//おはようと表示される

var aisatsu = "こんばんは";
alert(aisatsu);//こんばんはと表示される

これを実行すると自分の意図した通りの動きをしてくれます。しかしどの参考書をみても変数の中身を変えるときには、変数宣言varを省いています。これではvarを何度も書くのはなにか悪いことがあるのでは・・・、と思えてきます。

 Javascript同一関数内でvar xを二度宣言してしまった場合、そのページを... - Yahoo!知恵袋
知恵袋の話題ですが、似たような質問をしている方がいました。書いてあることは難しいですが要するに問題はなさそうです。

どういった理屈で大丈夫なのかが分からないので更に調べていくと、「変数の巻き上げ」というものに行き着きました。

変数の巻き上げ


知らないと怖い「変数の巻き上げ」とは?|もっこりJavaScript|ANALOGIC(アナロジック)

var - JavaScript | MDN

 JavaScriptの変数の仕様として、変数の巻き上げというものがあります。

JavaScriptは変数宣言をすべて拾ってから、コードを実行していくらしいです。

var aisatsu = "おはよう";
alert(aisatsu);

var aisatsu = "こんばんは";
alert(aisatsu);

とさっき書いていましたが、実際に実行されているのは

var aisatsu;
aisatsu = "おはよう";
alert(aisatsu);

aisatsu = "こんばんは";
alert(aisatsu);

というコードのようです。要するに変数宣言があるたびに毎回宣言をしているのではなく、一旦変数宣言を探し尽くしてから、コードの最初に変数を宣言してから実行していくということです。

var cat = "ミケ";

/*いっぱいコードを書く*/

var dog = "ポチ";

/*いっぱいコードを書く*/

var mouse = "◯ッキー"

言葉じゃわかりづらいので実際にこんなコードを書いたとすると、

var cat,
    dog,
    mouse;
    
cat = "ミケ";

/*いっぱいコードを書く*/

dog = "ポチ";

/*いっぱいコードを書く*/

mouse = "◯ッキー"

というように解釈されるわけです。ということは、

dog = "ポチ"
/*なにかいっぱいコードを書く*/
var dog;

と書いたとしても変数宣言は結局先頭に持っていかれるので、問題なく動作するわけです。動作には問題が無いですが、分かりづらくなるので変数宣言は先頭に持って来るべきです。

0 件のコメント:

コメントを投稿