2005-12-02 ========== ECMAScript での var ------------------- Reference URI: http://lowreal.net/logs/2005/12/02/3 Written Time: 2005-12-02T17:42:06+09:00 Tags: javascript script prog 前に書いた気がするけど、ECMAScript の var は Io の setSlot に似ている。 var foo; と書くと、既存のスコープの変数オブジェクトのプロパティに foo が作られる。そして foo = "1"; を書くと、スコープチェインの最初に、作られた foo プロパティを発見するため、そこに 代入される。 一方 foo = "1"; を var 無しにいきなり書いた場合、スコープチェインの末 Global オブジェクトにいきつき Glo bal オブジェクトのプロパティに新たに勝手にfoo が作られて代入される。 // Global Code の開始// Scope Chain: [Global]// Variable Object: Global//----// V ariable Object (Global)// のプロパティ foo に "foo" が代入される。var foo = "foo" ;// 上に同じvar bar = "bar";function foobar() { // Function Code の開始 // 新たに Activation Object (=このコンテキストでのVariable Object) が作られる。 / / (このとき arguments プロパティが自動的にセットされる。) // Scope Chain: [f oobarActivationObj, Global] // foobarActivationObj は仮の名前で実際にはアク セスできない。 // Variable Object: foobarActivationObj // Variable Object ( foobarActivationObj) // のプロパティ foo に "fbfb" が代入される。 var foo = "fbfb"; // Identifier があると Scope Chain を辿る。 // この場合最初の foob arActivationObj に foo を発見できる。 foo = "bfbf"; // この場合最初の fooba rActivationObj に 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, foobarActivati onObj, 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 もそうだけど、「見えないオブジェクト」がいくつかあってなかなか怖い 。