5. FunctionExpression(関数式)
var f = function() {
alert("func!");
}
f(); // 実行
if文などで(ry
関数を作る際には名前がなく、作った関数を変数fに代入しているだけ
なので
「無名関数」
などと呼ばれます。
Proprietary and Confidential to Lanchester Co.,LTD. Page 4
6. ~Declarationと~Expressionの違い
f(); // 実行可能
function f() {
alert("func!");
}
g(); // 実行不可
var g = function() {
alert("func!");
}
FunctionDeclarationはプログラムの実行に先立って評価されるためス
コープ内のどこにあっても問題なく実行できる。
FunctionExpressionは変数への関数(ポインタ的)代入が行われるまで
はundefined(未定義)となるため定義前には実行できない。
Proprietary and Confidential to Lanchester Co.,LTD. Page 5
7. 通称「名前付き無名関数」
var f = function n() {
// ココ!
}
f(); // 実行可能
n(); // 実行不可
この形式が通称「名前付き無名関数」と呼ばれる状態。
ここで付けられた名前「n」は「ココ!」の中、つまり自分自身のスコープ
からしか参照できない。
何に使うねん・・・なんて思っちゃダメ。
無名関数を作りつつ再起処理を書きたいときに使えるのです!
Proprietary and Confidential to Lanchester Co.,LTD. Page 6
8. 関数もプロパティ(~Declaration編)
1. alert(typeof(f));
2. function f() { alert("func!"); }
3. alert(typeof(f));
4. f = "string!";
5. alert(typeof(f));
概念的な実行順序は2→1→3→4→5となる。
2でfというプロパティに関数の代入が行われ、
1はfが関数のため「function」という表示がされ、
3でも当然「function」が表示される。
4で通常の文字列が代入されるため、
5では「string」と表示される。
Proprietary and Confidential to Lanchester Co.,LTD. Page 7
9. 関数もプロパティ(~Expression編)
1. alert(typeof(f));
2. f = function() { alert("func!"); }
3. alert(typeof(f));
4. f = "string!";
5. alert(typeof(f));
実行順序は上から1→2→3→4→5となる。
1ではfが未定義のため「undefined」と表示される。
2でfというプロパティに関数の代入が行われるため、
3では「function」という表示がされる。
4で通常の文字列が代入されるため、
5では「string」と表示される。
Proprietary and Confidential to Lanchester Co.,LTD. Page 8
10. Functionオブジェクト
ECMAScriptが標準的に持っているオブジェクト。
function f() {};
var f = function() {};
var f = new Function();
これらは(生成のタイミング以外ほぼ)等価です。
どっちがどっちのシンタックスシュガーという関係ではなく、内部的な変
数スコープの扱いが多少違います。
が、今回は同じものと思っておいて問題ありません。
※ 別の機会にちょっとだけ触れます
Proprietary and Confidential to Lanchester Co.,LTD. Page 9
11. Functionオブジェクト
function f() {
alert("func!");
};
に相当するFunctionオブジェクトの構築は
var f = new Function('alert("func!");');
のような形になります。
Proprietary and Confidential to Lanchester Co.,LTD. Page 10
12. 高階関数
「関数を引数にとる」、または「戻り値を関数とする」関数。
function add(a, b) { return a + b; }
function sub(a, b) { return a - b; }
function exec(func, a, b) { return func(a, b); }
alert(exec(add, 2, 3)); // 関数としての「add」を渡している
そもそもプロパティとして関数を持っているので引数に渡すのも戻り値
で返すのも楽々。
この2つが簡単にできると「あのJava」が苦手なクロージャを簡単に作れ
ます。
が、クロージャについては割愛。
Proprietary and Confidential to Lanchester Co.,LTD. Page 11
13. 引数の個数(オーバーロードその1)
function disp(message) {
alert(message);
}
よく見かける(?)こんな関数を次のように呼び出すと・・・
disp(); // 「undefined」と表示
disp("Hello"); // 「Hello」と表示
disp("Hello", "Good Bye"); // 「Hello」と表示
渡された実引数が順に仮引数に入っていく。
引数の数などは特にチェックされない。
Proprietary and Confidential to Lanchester Co.,LTD. Page 12
15. argumentsオブジェクト
argumentsオブジェクトと引数を同時に扱うことも可能
function dispTotalScore(message) {
var score = 0;
for(var i=1; i<arguments.length; i++) {
score += arguments[i];
}
alert(message + score);
}
dispTotalScore("Score is ", 10, 20, 30); // 「Score is 60」
arguments[0]には当然messageと同じものが入っている。
Proprietary and Confidential to Lanchester Co.,LTD. Page 14
16. 引数の型違い(オーバーロードその2)
var d = new Date(2011, 5, 10); // 月は0~11
var d = new Date("June 10, 2011");
この2つは全く同じ日付「2011/06/10」を返すが、引数の個数、型が
いずれもバラバラ。
function myDate(yyyy, mm, dd) { … }
function myDate(dateString) { … }
こんな風に書いちゃうと当然上書きされてしまう。
どうすれば?
Proprietary and Confidential to Lanchester Co.,LTD. Page 15
17. 自分で(都合の良いように)頑張る
function dispType(v) {
if( isNaN(v) ) {
if( v instanceof Array ) {
alert("Array");
} else {
alert("String");
}
} else {
alert("Number");
}
}
dispType([1,2]);
dispType("str");
dispType(12);
Proprietary and Confidential to Lanchester Co.,LTD. Page 16
18. Functionオブジェクトで引数
var f = new Function("a", "b", "c", "return a+b+c");
var f = new Function("a, b, c", "return a+b+c");
var f = new Function("a, b", "c", "return a+b+c");
コンストラクタに渡された最後の引数が関数本体、その前に渡されたも
のを文字列としてカンマで連結したものが引数の名前となる。
var f = new Function("a, b,", "c", "return a+b+c"); // エラー
var f = new Function("a, 0, c", "return a+b+c"); // エラー
Proprietary and Confidential to Lanchester Co.,LTD. Page 17