Hatena::Groupjavascript

emergentのJavaScript入門日記

 | 

2008-10-12

JavaScriptはプロトタイプベースのオブジェクト指向言語、という話

19:24 | JavaScriptはプロトタイプベースのオブジェクト指向言語、という話 - emergentのJavaScript入門日記 を含むブックマーク はてなブックマーク - JavaScriptはプロトタイプベースのオブジェクト指向言語、という話 - emergentのJavaScript入門日記

せっかくだしまるごとJavaScriptを最初から読んでいる。

読みながら重要そうなところをメモ。よく見たら筆者は小飼弾さんだった。

JavaScriptには2種類のオブジェクトがある

プリミティブ(primitive)とオブジェクト(Object)がある。

プリミティブ型は中にオブジェクトを詰め込めない。

オブジェクトは入れ子でオブジェクトをどんどん詰め込める。

オブジェクトはただのハッシュ

配列も、キーが数値であるだけのハッシュ。

オブジェクトプロパティもハッシュエントリー。

関数もオブジェクトだからプロパティに設定できる。

設定したものがオブジェクトメソッド

var hello = function() {};
hello.world = function() { return "hello" };

プロトタイプとnew

オブジェクトプロパティは簡単に上書きできてしまう。

プロトタイプ(prototype)は上書きできない。「隠しメソッド」のようなもの。

プロトタイプ内のメソッドはそのままでは使えず、newする必要がある。

var Hello = function() {};
Hello.prototype.world = function() { return "hello" };
var hello = new Hello();

だからJavaScriptはプロトタイプベースのオブジェクト指向言語と呼ばれる。

(他にはクラスベースの言語がある)

JavaScriptはプロトタイプベースのオブジェクト指向言語、という話(2)

22:36 | JavaScriptはプロトタイプベースのオブジェクト指向言語、という話(2) - emergentのJavaScript入門日記 を含むブックマーク はてなブックマーク - JavaScriptはプロトタイプベースのオブジェクト指向言語、という話(2) - emergentのJavaScript入門日記

継承の基本は、以下の3行らしいということ。

function child(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

childが子クラス、oが親クラスのオブジェクト

このreturnより前の行にメソッドを追加していくことで継承を実現できるそうな。

本に書いてあるコードをそのまま持ってくるのもアレなので、手前味噌な感じで作成。

var Human = function() {};
Human.prototype.hello = function() { return "hello!"; };

function Ossan(o) {
    function F() {};
    F.prototype = o;
    F.prototype.hello = function() { return "oissu!"; }
    F.prototype.laugh = function() { return "gufufu"; }
    return new F();
}

var human = new Human();
print(human.hello());
//print(human.laugh());

var yamada = Ossan(human);
print(yamada.hello());
print(yamada.laugh());

Humanオブジェクトは挨拶(hello)メソッドだけを持っている。

それを継承してOssanオブジェクトを作成。

Ossanの挨拶は「おいっす」で、さらにlaughメソッドも持っている。

コメントアウトしている部分は外すとエラーが出る。

実際に動作させるとこんな感じ。*1

$ js inherit.js
hello!
oissu!
gufufu

追記

var Human = function() {};
Human.prototype.hello = function() { return "hello!"; };

のところは、

var Human = function() {
    this.hello = function() { return "hello!"; };
};

という書き方の方がクラス定義っぽくてよさげ。

追記2

と思ったけど、上記だとprototypeプロパティと関係ないところにメソッドを格納しているので結局違うことやってることになる。

あまちゃん氏の記事によると、

var Human = function() {};
Human.prototype = {
    hello: function() { return "hello!"; }
};

となってるので結局一緒かな。

ちなみに、この書き方の場合はhello:〜の行の最後にセミコロンをつけたままだとエラーが出た。

ハッシュの中(つまり文末でない)だから当然か。

プリミティブ型

undefined

null

ブール型

数値型

文字列型

オブジェクト/プリミティブ : JavaScript | findxfine -Web制作に関する覚書-

ですって。

*1:実行にはUbuntuspidermonkey-binを利用しています->参考

 |