最終更新日: 2026-07-24
TOP(About this memo)) > 一覧(JavaScript) > 関数オブジェクト・スコープ
()をつけると呼び出せるというのは関数だけが持つ特徴。function hello(message) {
alert(message);
}
hello("word");
var hello = function(message) {
alert(message);
}
hello("word");
var hello = new Function("message", "alert(message);");
hello("word");
alert(alert); とやると "function alert() { [native code] }" のように出力される。
[native code] は、この関数の実行がブラウザの内部処理で行われる(JavaScriptで書かれた定義がない)ことを意味する。hello.length で参照可能。argumentsを使えば実現可能。Functionのプロトタイプには以下の特別なメソッドがある。どちらも関数オブジェクト(Functionで生成されたインスタンス)で利用可能。
Function.prototype.apply(thisArg, argArray)Function.prototype.call(thisArg[, arg1, ...])function ghi(arg1, arg2) {
alert(arg1 + arg2);
}
ghi.apply(null, ["a", "b"]);
ghi.call(null, "x", "y");
thisでアクセスできるオブジェクトを指定する。nullやundefinedを指定するとグローバルオブジェクトになる(ブラウザではWindowオブジェクト)。varを使って変数を定義 → ローカル変数varを使わずに変数を定義 → グローバル変数function foo() {
for (var o in arguments) {
var x = arguments[o];
}
alert(x); // -> "c"
}
foo("a", "b", "c");
var foo = 1;
var bar = 2;
function myfunc() { var a = 1; }
myfunc();
var foo = 1; var bar = 2; まで実行された時点で、トップレベルのスコープオブジェクト(Global Object)に2つの識別子が定義される(プリミティブなので、値もセットで格納される)。function myfunc { var a = 1; } まで実行されると、スコープオブジェクト(この場合はトップレベルなのでGlobal Object)にmyfuncという識別子が定義され、この識別子とセットで関数オブジェクトへの参照が格納される。myfuncの関数オブジェクト内には、プロパティとして、関数が定義されたときに有効なスコープオブジェクト(この場合はGlobal Object)への参照が作成される。myfunc(とその引数の値)のローカル変数を持つ新しいスコープオブジェクトが生成される。この新しいスコープオブジェクトは、関数を呼び出した時に参照したスコープオブジェクト(この場合はGlobal Object)を継承する。
myfunc scope -(継承)-> Global Objectmyfunc内からbarを参照するとき、まずmyfunc scopeを見に行き、myfuncのスコープにbarがなければ、継承元のGlobal Objectを見に行くことになる(スコープチェーン)。myfunc()が完了しmyfunc()のスコープオブジェクトが参照されなくなると、ガベージコレクションが起動し解放される。
var test = myfunc() と書いた場合、Global Objectにはtestという識別子とmyfuncの実行結果への参照が格納されるが、myfuncは何も返していないためtestはundefinedになる。myfuncが以下のようになると話が変わる。function myfunc() {
var a = 1;
return function() { return a++; };
}
function() { return a++; } がクロージャである。
myfuncという識別子が定義され、関数オブジェクトへの参照が格納される点までは変わらない。ただし var test = myfunc() まで実行されたタイミングで、myfuncのスコープオブジェクトの生成に加え、クロージャの関数オブジェクトが生成され、この関数オブジェクトはmyfuncのスコープオブジェクトへの参照をプロパティとして持つ。testにはクロージャの関数オブジェクトへの参照が格納される。test()によってクロージャを呼び出すと、クロージャのスコープオブジェクトが定義され、そのスコープオブジェクトはmyfuncのスコープオブジェクトを継承する。クロージャ自身のスコープオブジェクトは空なので、継承元のmyfuncのスコープオブジェクトを見に行く。iを参照してしまうため。var elems = document.getElementsByClassName("myClass"), i;
for (i = 0; i < elems.length; i++) {
elems[i].addEventListener("click", function () {
this.innerHTML = i;
});
}