前に書いた気がするけど、ECMAScript の var
は Io の setSlot に似ている。
var foo;
と書くと、既存のスコープの変数オブジェクトのプロパティに foo が作られる。そして foo = "1";
を書くと、スコープチェインの最初に、作られた foo プロパティを発見するため、そこに代入される。
一方 foo = "1";
を var
無しにいきなり書いた場合、スコープチェインの末 Global オブジェクトにいきつき Global オブジェクトのプロパティに新たに勝手に foo
が作られて代入される。
// Global Code の開始
// Scope Chain: [Global]
// Variable Object: Global
//----
// Variable Object (Global)
// のプロパティ foo に "foo" が代入される。
var foo = "foo";
// 上に同じ
var bar = "bar";
function foobar() {
// Function Code の開始
// 新たに Activation Object (=このコンテキストでのVariable Object) が作られる。
// (このとき arguments プロパティが自動的にセットされる。)
// Scope Chain: [foobarActivationObj, Global]
// foobarActivationObj は仮の名前で実際にはアクセスできない。
// Variable Object: foobarActivationObj
// Variable Object (foobarActivationObj)
// のプロパティ foo に "fbfb" が代入される。
var foo = "fbfb";
// Identifier があると Scope Chain を辿る。
// この場合最初の foobarActivationObj に foo を発見できる。
foo = "bfbf";
// この場合最初の foobarActivationObj に bar を発見できないため
// Scope Chain を辿り、Global で bar を発見する。
bar = "bzbz";
// この場合 Scope Chain をたどって、Global に行き着いても発見できないため
// 勝手に Global に baz プロパティを作る。
baz = "baz";
baz.foo = "foo";
with (baz) {
// with は Scope Chain の先頭に
// 指定オブジェクトを突っ込む
// Scope Chain : [baz, foobarActivationObj, Global]
foo = "bar";
// Variable Object は変わらない
var f = "!!!";
}
baz.foo; //=> "bar"
baz.f //=> undefined
f; //=> "!!!"
}
foobar();
foo; //=> "foo" 最初にグローバルで代入したまま
bar; //=> "bzbz" 書き換えられている
baz; //=> "baz" グローバルで一切でてきていないのに存在する
Io の場合 =
(updateSlot) はスコープチェインに Identifier を発見できない場合例外が発生する。現在の変数オブジェクトのスロットに突っ込むときは :=
(setSlot) を使用する。Io は明確な決まりがあるんだけど、ECMAScript は曖昧。気が付くと Global オブジェクトにプロパティがだらだらできたりする。
微妙にわかりにくいのは、Global Code においての Variable Object が Global で、変数に this.foo
というようにアクセスできるのに対し、Function Code の Variable Object には一切触れないこと
ときどき関数中で var a = b = c = 0;
って書いているのを見かけるけど、この場合の b, c は Global オブジェクトのプロパティ (または途中であるならその変数オブジェクトのプロパティ) になる。var a, b, c; a = b = c = 0;
とか書くのが正解。
Prototype Chain もそうだけど、「見えないオブジェクト」がいくつかあってなかなか怖い。
- トップ
-
javascript
-
ECMAScript での var
- トップ
-
script
-
ECMAScript での var
- トップ
-
prog
-
ECMAScript での var