続・JavaScript 再入門
一応、一通り読んだ。
JavaScript、自分で考えていたよりいろいろな書き方ができる。
それが故に、洗練されたものをつくるためには、「良いパーツ」を選んで使う必要がありそうだ。
今回はJavaScriptのメインともいえる、関数に触れてみる。
関数はオブジェクト
JavaScriptの関数は、オブジェクトである。複数の名前(識別子)と値を持つことができる。
関数の定義方法として以下の2つの書き方があるが、
function add(a, b) { return a + b; };
var add = function (a, b) { return a + b; };
関数がオブジェクトであることを意識できるので、後者の書き方がベターである。
関数、4つの呼び出しパターン
関数は、呼び出される際に、2つのパラメータ、this
と arguments
を自動的に受け取る。
但し、this
に関しては、関数の呼び出され方によってセットされる値が異なる。
メソッド呼び出しパターン
あるオブジェクトのプロパティとして関数を定義した場合、メソッドと呼ぶ。
var someObject = { value : 0, add : function (someNumber) { this.value += typeof someNumber === 'number' ? someNumber : 1; } }; someObject.add(); console.log(someObject.value); // 1 someObject.add(2); console.log(someObject.value); // 3
この場合、this
は someObject そのものが渡される。
関数呼び出しパターン
関数をオブジェクト内部に定義しなかった場合、JavaScript唯一のオブジェクト、グローバルオブジェクトのプロパティとなる。
このパターンを関数呼び出し、と書籍では定義してある。
var add = function (a, b) { return a + b; }; var sum = add(3, 4); // sum は7
この場合、add から見た this
は グローバルオブジェクト そのものとなる。
コンストラクタ呼び出しパターン
new をつけて呼び出すことを前提としたパターン。
// コンストラクタ関数 var Stat = function (string) { this.status = string }; // get_status というパブリックメソッドを // Stat のすべてのインスタンスで利用可能とする Stat.prototype.getStatus = function () { return this.status; }; var myStat = new Stat("confused"); console.log(myStat.getStatus()); // confused
この場合、new で作成されたインスタンスそのものが、this
にセットされる。
コンストラクタ関数は、new
をつけて呼び出す前提なので、慣例として大文字始まりにすることが多い。
apply呼び出しパターン
JavaScriptにもともと備わっているapplyメソッドで、関数を呼び出せる。
var add = function (a, b) { return a + b; }; var array = [3, 4]; var sum = add.apply(null, array); // sum は 7 // status をメンバに持つオブジェクトを作成 var statusObject = { status : "OK" }; // 先ほどのコンストラクタ関数呼び出しパターンで定義した、Stat.prototype を statusObject で呼び出す console.log(Stat.prototype.getStatus.apply(statusObject); // OK
applyメソッドは、第一引数にthis
にセットしたいオブジェクト、第二引数に呼び出す関数の引数を渡せる。
継承していないはずのprototypeのメソッドさえ呼び出せる。
いろいろできるけど
大きな機能を書くときには、メソッド呼び出しパターンがいいことはいうまでもない。今回触れていないが、名前空間的なこともこれで実現可能だ。
ライトに試す場合は、関数呼び出しパターンで十分。でもすぐリファクタしたくなる可能性あり。
apply呼び出しパターンは・・・使い時が分からない。
コンストラクタ呼び出しパターンは、今回読んだ書籍では推奨されていない!何故 new
がダメなのか、次回見ていきたい。