Functionオブジェクト

JavaScriptで関数を定義するには、"function foo() {}"といつものに加えて、Functionオブジェクトを作ることでも定義出来るらしい。


なので、こんな書き方も出来る。

function hello(name) {
  var name = name;
  alert("Hello" + name);
}

hello("goodman"); // "Hello goodman"

これは、

var name = "name";
var body = "var name = name;\n";
body += "alert('Hello ' +" + name + ")";
var hello = new Function(name, body);

hello("goodman"); // "Hello goodman"

と一緒。
ただ、Functionオブジェクトは使用されるたびに評価されるので、何度も使うときは普通に関数を宣言した方がいいよ!コンパイルされるので、と「Core JavaScript1.5 Guide」には書いてあります。
処理の中で文字列を組み立てて関数として評価したい場合とかは使えそう。


Functionオブジェクトにはcall()とapply()、toString()関数が定義されている。
call()とapply()は、第一引数にコンテキストオブジェクト、第二引数に呼び出し元の関数の引数を指定すれば、呼び出し元の関数を実行できる。

hello("goodman");

これは、

hello.call(this, "goodman");

と一緒。
call()は引数が複数の場合にリストを直接指定するけど、apply()は配列を指定すればいいので何となくapply()の方が便利な予感。
これでprototype.jsのbind()とbindAsEventListener()の意味が分かりました。
何となくthisの便利さが分かってきたような気がするんだかしないんだか!


Function.toString()は関数を文字列にして返す関数。

hello.toString();  //function anonymous(name) { var name = name; alert("Hello " + name); }

これはどんな時に使えばいいんだろう。イメージ湧かないなぁ。。。


ともあれ、FunctionオブジェクトはprototypeとかconstructorとかJavaScriptを理解する上で欠かせないプロパティを持っているのであなどれない。
あーだからfunction定義しないとprototypeが使えないのか!とか。


それにしても、JavaScript Shell便利!
ブラウザから実行出来るので、ソーシャルブックマークとかでブックマークしておけばどこでもJavaScriptを試せて助かります。