JavaScriptのデータ型と変数

初めてのjavascriptの2章です!データ型と変数について。

名前の付け方

jsでの変数名や関数名の付け方が書いてありました。ソースの可読性からいって名前は本当に重要。

  • 省略しない簡潔な名前を

これはどの言語でも同じ。たった数文字のために名前を省略しても、可読性が落ちるだけでいいことない。逆に長すぎでも可読性は落ちる。

//なんのことか分かんない
var iRt;  

//分かるように書くべし
var interestRate;  //金利
  • キャメルケースを用いる

変数名、関数名は小文字で初めてキャメルケースを用いる。

var currentTime;
function currentTime();
  • 変数名には名詞、関数名には動詞を

これは特に意識してなかった。rubyだとgetterメソッド名にも名詞を使うことは多い。

var currentTime;
function getCurrentTime(){}
  • プライベート変数は「_」で始める

これは、PythonJavaから影響を受けたらしい。「_」で始めたからプライベートになるとかではなく、ただの書き方。

var _currentTime;


そもそもjsでは変数をプライベートとして扱う際に、特に宣言はいらないとのこと。宣言される際の環境によって決まるらしい。ここは後の章で勉強する。

プライベートメンバはコンストラクタにより作られます。通常は、varにより定義される変数とコンストラクタの引数がプライベートメンバになります。

function Container(param) {
 this.member = param;
 var secret = 3;
 var self = this;
}

このコンストラクタは、param、 secret、 selfの3つのプライベートインスタンス変数をつくります

スコープ

スコープとは、変数の有効範囲。同じ変数名で同じスコープを持つ変数は同一のものと見なされる。
jsのスコープは単純。グローバルかローカルか。
関数内で、varで変数を定義すると、その変数はローカル変数になり、その関数内でのみ有効になる。つまり、スコープは、その関数内。
一方、関数内で宣言しても、varをつけないとグローバル変数になる。


以下の例では、最初のhogeと関数内で宣言されたhogeは別の変数になる。

//グローバル変数
hoge = "hoge";

function outHoge(){
  //ローカル変数
  var hoge = "hogehoge";

  //ここでのhogeはローカル変数のhogeを参照する
  document.write("In function" + hoge + "<br />");
}

outHoge();
document.write(hoge + "<br />");

//結果
//In function hogehoge
//hoge


一方、関数内でvarをつけないで宣言すると、hogeグローバル変数になり、1行目のhogeを同じものを指す。よって、outHoge内で、"hoge"から"hogehoge"に値が上書きされる。

hoge = "hoge";

function outHoge(){
  //グローバル変数hogeの内容が上書きされる
  hoge = "hogehoge";
  document.write("In function" + hoge + "<br />");
}

outHoge();
document.write(hoge + "<br />");

//結果
//In function hogehoge
//hogehoge


この例のように、グローバル変数スクリプト全体に影響があるため、極力使わないようにする。
また、ローカル変数をグローバル変数として宣言するミスをなくすため、変数の宣言はグローバル、ローカルに関わらずvarを用いて宣言するべし。
varを用いても、関数内で宣言しない場合、その変数はグローバル変数になる。

var hoge = "hoge";

function outHoge(){
  var hoge = "hogehoge";
  document.write("In function" + hoge + "<br />");
}

outHoge();
document.write(hoge + "<br />");

//結果
//hogehoge
//hoge
  • ブロック内の変数

jsではブロック内で宣言された変数は、そのひとつ外側のスコープを持つ(ブロック文ではスコープは生成されなかった。詳しくは追記にて)。つまり、関数内でブロックが定義されていた場合は関数内からはその変数を参照できるし、関数の外で定義されたブロック内で定義された変数はグローバル変数になる。


データ型

jsのデータ型は3つしかない。string, nurmeric, boolean。でも、String, Number, Booleanオブジェクトもある。これらはObject型に属するオブジェクトで、3つのデータ型とは別物。ややこしい( ゚д゚)

  • 変数には型はない

ここはrubyと同じ。変数が参照できる型は固定されないようだ。String str = "hoge"; という風にはならない。

var hoge = "hoge";
document.write(hoge + "<br />");
var hoge = 1;
document.write(hoge + "<br />");

//結果
//hoge
//1
  • 偽になる値

jsでは、以下の値はfalse(偽)と見なされ、他はtrueと見なされる(false, undefinedを書き損ねましたので追記)
0, "", null, NaN(Not a Number) , false, undefined

  • nullとundefinedの違い

これがよく分からなかった。(javascripterさんから教えて頂いたので、追記しました

本によると、

  • null

定義されたが、まだ値が代入されていない状態の変数

  • undefined

変数は宣言されたがまだ初期化されていない状態


日本語でおk(泣)宣言と定義って同じじゃないのか?まだ値が代入されていないってことは、それは初期化されてないってことじゃないの?
調べてみる。

ここによると、以下のような分析がされてる。

null == undefined #=> true
null === undefined #=> false
typeof null #=> Object
typeof undefined #=> undefined


「==」を使う限りは同じ意味。クラス型(jsにはクラスはない)は違うけど、オブジェクトとしては同じ?
う〜ん。まぁ、nullかどうか判定したかったら「undefined == target」としてやればいいってことは分かったし、最初から細かいこと気にしてても意味ないからここまでの理解でおk。必要になったら詳しく調べればいい。

追記

id:javascripterさんから指摘を頂きました>< ありがとうございます!こういうコミュニケーションがあるからブログっていいすね(*´艸`)

  • false、undefinedも偽です

うぉ。完全に書き損ねました。

  • ブロック文はスコープを作りません...
  • undefinedはグローバル変数で書き換え可能なのに対し、nullは予約語です...
  • undefined==nullはtrueなので、nullかどうか判定するには...


この3つについては長くなるのでJavaScriptのデータ型と変数の追記(jsのスコープ, nullとundefinedの違いについて) - Slow Danceに書きました