Hatena::ブログ(Diary)

西尾泰和のはてなダイアリー

2013-08-04

new演算子の挙動について

拙著「コーディングを支える技術」のp.204では、JavaScriptのnew演算子の挙動を例にオブジェクトが作成される過程の説明をしています。しかし、ソースコード中の囲み数字の個数と、ソースコードの直後の箇条書きの個数が両方4個であることが原因で混乱のもとになるようです。そこでこのページを全体的に再構成することにしました。

修正前の構造

 さらに、プロトタイプを使った処理を楽に書けるような演算子も用意されています。次のコードでは関数Counterにnewという演算子を付けて呼び出しています。

(サンプルコード)

 関数にnewを付けて呼び出すと、次の4つの処理が行われます。

(箇条書き)

 このコードでは、まず(2)で…(以下サンプルコードの解説)

修正後

 さらに、プロトタイプを使った処理を楽に書けるように、newという演算子が用意されています。関数fにnewを付けて呼び出すと、次の4つの処理が行われます。

  • (a)新しいオブジェクトxを作る
  • (b)作られたオブジェクトxのプロトタイプを、関数fのプロトタイプに変更する
  • (c)作られたオブジェクトxをthisに入れて関数fの本体を実行する
  • (d)オブジェクトxを返す

 実際のコードで見ていきます。

var Counter = function() {
    this.count = 0; //                        (1)
}

Counter.prototype.push = function(){ //       (2)
    this.count++;
    console.log(this.count + "匹");
}

var c1 = new Counter(); //                    (3)
c1.push(); //-> 1匹
c1.push(); //-> 2匹
var c2 = new Counter();
console.log(c1.push === c2.push) //-> true // (4)同じ物

 このコードは、まず(2)で関数Counterのプロトタイプにpushという名前で新しい関数を追加しています。次に(3)の new Counter() で上記(a)〜(d)の処理を行います。まず空っぽの新しいオブジェクトを作ります((a))。それから、そのオブジェクトのプロトタイプをCounterのプロトタイプに変更します((b))。このプロトタイプにはpushが入っています。次に、このオブジェクトをthisに入れてCounterが呼び出されます((c))。Counterの中には(1)のように書かれているので、ここでこのオブジェクトにcountという名前で、0という値が追加されます。最後に、この「pushの入ったプロトタイプを持っている、countの入ったオブジェクト」が返ります((d))。無事図11.6右の構造を作ることができました。(4)がtrueになっていることで、push関数を共有できていることがわかります。

さいごに

拙著「コーディングを支える技術」の読者のみなさんから頂いたご質問・ご感想には、このような感じで補足記事を書いて行きたいと思っています。おきがねなくご質問・ご感想をお寄せ下さい。

拙著に関する他のエントリーは「「コーディングを支える技術」著者公式ページ」からたどれるようにします。

ukyoukyo 2013/08/04 21:48 誤:(b)作られたオブジェクトxのプロトタイプを、関数fのプロトタイプに変更する
正:(b)作られたオブジェクトxのプロトタイプを、関数fのprototypeプロパティに変更する
ですね(Function.prototype.bindはなしで)。

参考:
http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.2

nishiohirokazunishiohirokazu 2013/08/06 12:05 ご指摘ありがとうございます!

投稿したコメントは管理者が承認するまで公開されません。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/nishiohirokazu/20130804/1375584264