JavaScript: The Good Parts(1〜4章)

JavaScript書き始めてもなかなか他の言語みたいに馴染まないなぁと思ってたときに手にした一冊です。
実はこの本の内容が最初読んだ時には理解出来ず二度読みました。

この本を読んだことでようやくJavaScriptに入門出来た気がしたので感想を書きたいと思います。

1章 良いパーツ

  • ここではJavaScriptの良い点悪い点について簡単に書かれていて、この本の導入部分になっています。

2章 文法

  • ここではJavaScriptの文法を鉄道ダイアグラム用いて説明されています。

3章 オブジェクト

  • ここからがこの本の本編になっていると思います。
  • まずはオブジェクトの作り方や参照更新方法などひと通りわかりやすく説明されています。そして、prototypeについての説明も簡単にされていますがそんなものがあるという程度の説明になっていて、後の章で説明がされています。
  • また、typeofやfor inを使う際の注意点などについて書かれており、JavaScriptのオブジェクトを考えるときにはプロトタイプが大事であることを理解することが出来る章になっています。

4章 関数

  • JavaScriptで最も素晴らしいのは関数の実装方法だという書き出しで始まり、なにやら期待させられる章になっています。
  • ただhoge()の呼び出し方だけを紹介しているのではなく四つの関数呼び出し方法が紹介されているのもいいなぁと思いました。
メソッド呼び出しパターン
  • オブジェクトのプロパティとして関数を定義する方法ですね。
var obj = {
    name: "koba04",
    say: function() {
        return "My Name is " + this.name;
    }
};
関数呼び出しパターン
  • よくある関数の呼び出し方ですが、thisはグローバルオブジェクトになるので注意ですね。
function sum(a, b) {
    // thisはグローバルオブジェクト
    return a+ b;
}
sum(1,2);
  • また入れ子になった関数の中で外側の関数のthisを使いたい場合にthisを代入する変数名はthatが通例というのも初めて知りました。
var obj = {
    name: "koba04",
    say: function() {
        var that = this;
        return function() {
                // thisはグローバルオブジェクト
                return "My Name is " + that.name;
        }
    }
};
コンストラクタ呼び出しパタン
  • クラスがある言語を使っていると馴染みのあるパターンでつい使いたくなりますが、ここではオススメ出来ない方法として紹介されています。
  • その理由は後ほど説明がありますが、ここではnew付けずに通常の関数としても呼び出せるしその場合によくない事態が起きることがあるとしています。まぁthisがグローバルオブジェクトになるということですね。
apply呼び出しパターン
  • 個人的には、これがJavaScriptわからないなぁと最初に思った要素の一つであり、わかるようになった時に面白いなぁと思った部分でもあります。
var obj = {
     name: "koba04",
     say: function() {
         return "my name is " + this.name;
     }
}

console.log( obj.say.apply({ name: "koba03" }, []) );
// my name is koba03
  • その他にもarguments、例外、標準オブジェクトのprototype拡張、再帰、スコープ、クロージャ、コールバック、モジュール、カスケード、カリー化、メモ化についても紹介されていて、JavaScriptの関数の強力さがよくわかる章になっています。
  • 技術的に興味深いものばかりですが、その中からスコープ、クロージャを取り上げたいと思います。
    • コールバックはJavaScriptを使うとたくさんかなり書くことになり、個人的には好きな書き方だったりします。
スコープ
  • 他の言語をやっている人が違和感を感じる関数スコープについての説明がされているのですが、その中で変数の宣言は関数の先頭で全部やってしまうのがいいとありました。
  • 個人的にはこれに違和感を少し感じました。確かに関数の途中でvarで変数を宣言しても関数の先頭で変数宣言されたことになるので、実際の動作と同じように関数の先頭で宣言するのが正しいというのは理解出来ます。でも、途中でvarで宣言しておくことで、宣言以降でだけ使うことを意図している変数であることが明確になってわかりやすいのかなぁと思ったりしました。実際のgithubなどでソースを見てもそうしているのが多いのかなぁとも思います。
var hoge = function() {
// var date; 宣言はしない
:
:
// ここまででdateは使われないはず
var date = new Date();
// これ以降でdateを使おうとしていることがわかる。
}
クロージャ
  • しっかり意識しないとハマるなぁと思ったのはノード配列のonclickを登録していく例です。クロージャを使う場合はどの変数を参照しているのかを意識することがとても重要だなと感じました。
// ダメな例、どのnodeをクリックしても同じ値がalertで表示される。
var add_the_handers = function (nodes) {
    var i;
    for (i = 0; i < nodes.length; i += 1) {
        nodes[i].onclick = function (e) {
            alert(i);
        };
    }
};

// 良い例(i)をコピーしてonlickの関数に渡している
var add_the_handers = function (nodes) {
    var i;
    for (i = 0; i < nodes.length; i += 1) {
        nodes[i].onclick = function (i) {
            return function (e) {
                alert(i);
            };
        }(i);
    }
};

本のコードを引用


次の5章は継承についてですが、それは後日に。。