- 2008-11-23 (日) 23:17
- JavaScript
ようやく 8 章まで来ました。
だいぶ内容が難しくなってきたので、読んでもよく分からないものはちゃんと手を動かして理解するように心がけました。
ですが、最後のクロージャのところは正直理解できませんでした・・・。また後で読んでみます。
8 章 関数
8.1.1 入れ子型の関数
- 関数を他の関数の中に入れ子で定義できる。
- ただし入れ子にする関数のトップレベルで定義しなければいけない。if 文の中などでは定義できない。
8.1.2 関数リテラル
var f = function() { return x * x }; // 変数に格納したり
f[0] = function(x) { return x * x }; // 配列要素に格納したり
a.sort(function(a, b) { return a - b; }); // 別の関数に渡したり
var s = (function(x) { return x * x; })(10); // 定義してすぐに呼び出したり
8.2.1 省略可能な引数
- 関数を定義した時よりも少ない数の引数でその関数を呼び出した場合、省略された引数には undefined が設定される。
- この特徴を利用して、省略可能な引数を持つ関数を定義できる。
- ただしその際には、関数内で引数が省略された場合にデフォルト値が設定されるように処理する必要がある。
- また、省略可能な引数は引数リストの最後に記述する必要がある。
function f(o, a) { // a は省略可能とする
a = a || []; // a が省略されている場合は空の配列を生成
for(var p in o) a.push(p);
return a;
}
8.2.2 可変長の引数リスト(Arguments オブジェクト)
- Arguments オブジェクトは配列のようなオブジェクトである。
- 関数に渡された引数値は、関数定義値の引数に関わらず arguments[] 配列の要素に格納される。
function f(x, y, z) {
return arguments.length;
}
f(1, 2, 3); // 3
f(1); // 1
f(1, 2, 3, 4, 5); // 5。関数定義時の引数の個数に関わらず、任意の数の引数値を渡せる。
function max() { // 引数を定義しない
var m = Number.NEGATIVE_INFINITY;
for(var i = 0; i < arguments.length; i++) {
if(arguments[i] > m) m = arguments[i];
}
return m;
}
max(1, 10, 2, 3000, 400);
function f(x) {
alert(x); // 渡された引数値を表示
arguments[0] = null;
alert(x); // null
}
8.2.2.1 callee プロパティ
- Arguments オブジェクトの callee プロパティは、現在実行中の関数を参照する。
- 再帰処理を行う関数などで使用される。
function f(x) {
if(x < = 1) return 1;
return x * arguments.callee(x - 1);
}
f(5);
8.2.4 引数の型
- JavaScript は弱い型付き言語で、関数定義時に引数の型を宣言することはできないので、型を限定する場合は関数内で型のチェックを行う必要がある。
8.4 メソッドとしての関数
- 関数がメソッドとして呼び出された場合、this キーワードは呼び出されたオブジェクトを参照する。
- 関数がメソッドではなく関数として呼び出された場合、this キーワードはグローバルオブジェクトを参照する。
var f = function() { return this; };
f(); // 関数として呼び出し。Window オブジェクトが返る。
var o = { f: function() { return this; }};
o.f(); // メソッドとして呼び出し。o オブジェクトが返る。
var a = [];
var o = {
f: function() {
function g() { a.push(this); }
g();
a.push(this);
}
}
o.f();
alert(a[0]); // メソッドとして呼び出された関数内の入れ子関数として呼び出し。Window オブジェクトが表示される。
alert(a[1]); // メソッドとして呼び出し。o オブジェクトが表示される。
8.6 関数のプロパティとメソッド
- 関数は、実際には特殊なオブジェクトであるため、プロパティやメソッドを持つ。
8.6.1 length プロパティ
- Function オブジェクトの length プロパティには引数リストで宣言された引数の個数が設定される。
- arguments.length プロパティと異なり、関数の外でも使用できる。
// 宣言時の引数の個数と呼び出し時の引数の個数が一致していれば true を返す
// arguments.callee.length は check.length でも可
function check(a) {
return (arguments.length == arguments.callee.length);
}
check(1); // true
check(1, 2); // false
check(); // false
8.6.3 自分専用の関数プロパティの定義
- Function オブジェクトのプロパティであれば関数の実行を終了した後も値を保持し、次に関数が呼び出された時に使うことができる。
uniqueInteger.counter = 0;
function uniqueInteger() {
return uniqueInteger++;
}
uniqueInteger(); // 0
uniqueInteger(); // 1
8.6.4 apply() メソッドと call() メソッド
- あるオブジェクトのメソッドであるかのように関数を呼び出すことができる。
- 最初の引数に呼び出す関数の対象となるオブジェクトを指定する。
- call() メソッドの 2 番目以降の引数は、これから呼び出される関数に引数として渡される。
- apply() メソッドの場合は、第 2 引数に関数に渡す引数を配列形式で指定する。
var f = function(a, b) { alert(a * b); return this; };
f(1, 2); // Window オブジェクトが返る
var o = {};
f.call(o, 1, 2); // o オブジェクトが返る。メソッドとして実行されている。
f.apply(o, [1, 2]); // 〃
8.8.1 静的なスコープ
- JavaScript 関数のスコープは、実行時のスコープではなく定義時のスコープという意味で、静的である。
- 関数が定義されると、定義された関数の内部状態に、現在のスコープチェーンが保存される。
- 関数を入れ子で定義する場合は、スコープチェーンには入れ子関数の外側の関数が含まれる。
8.8.2 Call オブジェクト
- JavaScript インタプリタは関数が呼び出されると、関数のスコープにまず関数定義時のスコープチェーンを設定し、次に Call オブジェクトをスコープチェーンの先頭に追加する。
- arguments やローカル変数、仮引数は Call オブジェクトのプロパティになる。
8.8.3 名前空間としての Call オブジェクト
- Call オブジェクトを一時的な名前空間として使えば、グローバルな名前空間での変数名やプロパティ名の衝突を避けることができる。
8.9 Function() コンストラクタ
- Function() コンストラクタを使うと、JavaScript のコードを実行時に動的に生成してコンパイルできる。
- Function() コンストラクタを使うたびに、関数の本体が解釈され新しい関数オブジェクトが生成される。
- そのため、頻繁に呼び出される関数やループで使用すると、効率が悪くなる。
function f(x, y) { return x * y; }
var f = new Function("x", "y", "return x * y;"); // 上記関数文を Function() コンストラクタを使用した形で記述
関連する記事
Comments:0
Trackbacks:0
- Trackback URL for this entry
- http://www.sukechan.net/archives/110/trackback/
- Listed below are links to weblogs that reference
- JavaScript 第 5 版 8 章まとめ from sukechan.net

