「JavaScriptはprototypeベース」を再確認 - しろログ

「JavaScriptはprototypeベース」を再確認

2008/01/09

JavaScriptはprototypeベースのオブジェクト指向言語なんだぜー、
ということに慣れてきたところ、「prototypeベースの」という部分を忘れてはまった。

var Box = function() {};

Box.prototype = {
    toys: [],
    addToy: function(name) {
        this.toys.push(name);
    }
}

まず、こんな感じで、toysプロパティと、addToyメソッドを持った
Boxクラスを作ったつもりになる。

早速インスタンスを作るぜ。

var MyBox = new Box;
var YourBox = new Box;

おもちゃを入れるぜ。

MyBox.addToy('ball');
alert(MyBox.toys.length); // 1

YourBox.addToy('puzzle');
alert(YourBox.toys.length); // 2

げーん。1つだけ入れたつもりが、なぜか2個に…魔法の箱だぁ。

もちろん、下のような感じでも、

function a() {
    var MyBox = new Box;
    MyBox.addToy('ball');
    alert(MyBox.toys.length);
}

毎回新たに作ってるつもりだったのに……

a(); // 1
a(); // 2
a(); // 3

でもこれ、↓と同様だと考えれば納得できる

var a = [];
var b = a;

a[0] = 'hey';

alert(b[0]); // hey

newした時に、新しいオブジェクトは自分用に元のprototypeをコピるけど、
参照型の場合、コピるのはあくまでも「参照」だけで、参照してる先まではコピらないってコトかな。
上で言う「b = a」とだけしてる感じ。

(newが具体的に何をしてるかはこちら)

なので逆に、数値とか文字列とか、プリミティブ型は問題無い。

ちなみに、ECMAscriptでの定義は、

プリミティブ値 (Primitive Value)
プリミティブ値 (primitive value) は Undefined, Null, Boolean, Number, String 型のうちの一つの構成要素である。プリミティブ値は言語実装の最低レベルにおいて直接表されるデータである。
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/4_Overview.html

オブジェクト (Object)
オブジェクトは Object 型の構成要素である。序列のないプロパティの集合体で、それぞれのプロパティがプリミティブ値やオブジェクト、関数を含む。オブジェクトのプロパティに格納された関数はメソッドと呼ばれる。
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/4_Overview.html

こんな感じ。

とりあえず、この問題を避けるには、
コンストラクタ内で新しいオブジェクトを参照するようにしてやれば、OK。

var Box = function() {
    this.toys = [];
};

Box.prototype = {
    addToy: function(name) {
        this.toys.push(name);
    }
}

初期化はコンストラクタでしようぜ、という感じ。

カテゴリ:コンピューター

タグ:

トラックバックURI

http://blog.hakoniwa.net/archives/414/trackback/

コメント・ご質問

FLASH でゲームを作ろうとしている人は必見の情報、という…

「JavaScriptはprototypeベース」を再確認 - しろログ
記念すべき初トラバでございます。

おそらく FLASH でゲームを作ろうとしたとき、最初に悶 (more…)




コメント・ご質問


※スパム防止のため、表示まで時間がかかることがあります。