素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: twitter: @javascripter にどうぞ。

Callオブジェクト

JavaScript第5版を見ていたら、結構覚えてない物があったのでメモ。
まず、関数実行される時に、varで宣言された変数は、Callオブジェクトという物に登録される。

var f = function (a, b) {
  var c, d;
};
f(1, 2);

の場合だと、

var callObject = {
  c: undefined,
  d: undefined,
  __proto__: parentCallObject
};

で、with (callObject) {}みたいに囲まれてるようなイメージ。外側のスコープを表わすCallオブジェクトも登録されている。
で、呼び出す時に渡された仮引数が、実引数の変数と共に、同じCallオブジェクトに登録される。argumentsも同時に作られる。

var callObject = {
  c: undefined,
  d: undefined,
  a: 1,
  b: 2,
  arguments: {0: 1, 1: 2, length: 2: caller: func},
  __proto__: parentCallObject
};

グローバル変数はwindowとかで参照できて便利だから、Callオブジェクトも参照できるといいのになあ。
あと、

var obj = 'a';
var obj = obj || 'b';
alert(obj);

はaが表示されて、

var obj = 'a';
(function () {
  var obj = obj || 'b';
  alert(obj);
})();

はbが表示されるのは、変数を宣言するとあらかじめundefinedが代入されているだけで、Callオブジェクトとかはあんまり関係なかった。だから、変数が宣言されていなかったらオブジェクトを代入するっていう場合は、常にトップレベルでvar obj = obj || {};ってしなきゃいけない。