##JSにおいてプロパティと変数は同じもの。
- オブジェクトはプロパティの集合体。プロパティは、名前(キー)と値のペアである。
- 変数を宣言し格納するときは、キーと値のペアを指定している。
const obj = {x:3, y:5}; //キーと値のペア
const value = 1; //キーと値のペア
オブジェクトobjのプロパティとして x = 3, y = 1 が存在するのと同じように、value = 1 もまたオブジェクトのプロパティとして存在している。
=> グローバルオブジェクトのプロパティに存在している。
以下にその証明を書く。
const obj = {x:3, y:5};
const value = 1;
console.log(obj.x) //3
console.log(this.value) //1
//トップレベルコードのthis参照は、グローバルオブジェクトを参照している。
つまり、変数もまたグローバルオブジェクトのプロパティである。
##グローバル変数とローカル変数
変数名 | ローカル変数 | グローバル変数 |
---|---|---|
意味 | 関数内で宣言した変数。関数の引き数。 | 関数の外(トップレベルコード)で宣言した変数。 |
参照先 | その関数の中でのみ参照できる。 | プログラム全体からアクセスできる。 |
オブジェクト | Callオブジェクト | グローバルオブジェクト |
変数名解決 | Callオブジェクトのプロパティ、トップレベルコードのプロパティ | トップレベルコードのプロパティ |
注意点として、if文などで使われるブロックスコープはスコープを持たないので注意。 |
###Callオブジェクトについて
Callオブジェクトとは、関数が呼ばれたときに暗黙に生成されるオブジェクトのこと。そしてローカル変数とは、暗黙に生成されるオブジェクトのプロパティである。そのためローカル変数はCallオブジェクトの生存期間のみ利用可能である。
ただし上記には例外がある。それがクロージャ。
クロージャでは、関数を抜けたあともローカル変数は存在し続ける事ができる。
###変数名の解決
コード上に変数名を書いたときに、その値を探すことを変数名の解決という。
ローカル変数は、外側に向かって関数内のCallオブジェクトを探しはじめ、最後にグローバルオブジェクトのプロパティを探す。
##変数とプロパティの存在チェック
宣言していない変数は ReferenceError
存在しないプロパティへアクセスすると、undefined
console.log(x); //"x is not defined"
console.log(this.x); //undefined
//変数aの判定チェック
var a = 10;
if('a' in this) {
var b = a;
} else {
var b = 7;
}