続・JavaScript 再入門

一応、一通り読んだ。

www.amazon.co.jp

JavaScript、自分で考えていたよりいろいろな書き方ができる。

それが故に、洗練されたものをつくるためには、「良いパーツ」を選んで使う必要がありそうだ。

今回はJavaScriptのメインともいえる、関数に触れてみる。

関数はオブジェクト

JavaScriptの関数は、オブジェクトである。複数の名前(識別子)と値を持つことができる。

関数の定義方法として以下の2つの書き方があるが、

function add(a, b) {
    return a + b;
};
var add = function (a, b) {
    return a + b;
};

関数がオブジェクトであることを意識できるので、後者の書き方がベターである。

関数、4つの呼び出しパターン

関数は、呼び出される際に、2つのパラメータ、thisarguments を自動的に受け取る。

但し、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 がダメなのか、次回見ていきたい。