おもしろwebサービス開発日記

Ruby や Rails を中心に、web技術について書いています

prototypeがよくわからない件

ここ3日くらい、この本を読んでJavaScriptの基礎を学んでいました。

JavaScriptプログラミング入門 第2版

JavaScriptプログラミング入門 第2版

だいたい一通り流し読んだのですが、難しい部分がはしょられていて「なんでそうなるの?」という部分がいくつかありました。主にprototypeのとこ。
本だけではいかんともしがたい状況なのでググったのですが、それでもまだ曖昧な部分が残ります。


こればっかりに時間を割く訳にも行かないので、ひとまずわかったところとわからないところをまとめて、後日調べようかと思います。というわけで、以下個人的メモ。

prototypeわかったところ

こんな感じで、定義ずみのオブジェクトにメソッドを追加できる。
function hoge() {}
hoge.prototype.hello = function () {
  alert("hello!");
}
既存の組み込みオブジェクトのメソッドを変更できる
Date.prototype.toLocalString = function (){
   return this.getFullYear()+'年'+
   this.getMonth()+1+'月'+
   this.getDate()+'日'+
   this.getHours()+'時'+
   this.getMinutes()+'分'+
   this.getSeconds()+'秒';
}
継承ができる
function Animal () {}
Animal.prototype.isAnimal = function () {
   return true;
}

function Dog (name) {
   this.name = name;
}

Dog.prototype = new Animal();    // <------(1)

Dog.prototype.bark = function () {
   alert(this.name + ': わんわん');
}

pochi = new Dog('ぽち');
pochi.bark();
alert( pochi.isAnimal() );

prototypeわかってないところ

1.コンストラクタがあるオブジェクトを継承する場合。本にはこんな感じで書いてある*1
function displayInfo() {
  document.write(this.name);
}

function customer(name){
  this.name = name;
  this.displayInfo = displayInfo;
}

function goldCustomer(name, goldPoint) {
  this.base = Customer;
  this.base(name, goldPoint);
  this.goldPoint = goldPoint
}

goldCustomer.prototype = new customer;

上記のコードに加え

var customer1 = new goldCustomer("willnet", 100);
customer1.displayInfo();

としたときに、displayInfoが実行されるのはわかるけど、"willnet"が入っているのはcustomer1.base.nameなのでこのコードだとできないんじゃないかなと思った。
でも実際やってみたらできた。どういう理屈なんだろう。

2.組み込みオブジェクトの定義がどのように書かれているか

オブジェクトの定義でthis.hoge()みたいな形で書かれていたら、this.prototype.hogeを定義しても前者が有効になるというのが(4/4)知られざるJavaScriptの世界 - 知られざるJavaScriptの世界:ITproに書いてあった。ということは、prototypeで拡張できる組み込みオブジェクトは、this.hoge()のようにメソッドを定義していないことになる。ってことはDate.prototype.toLocaleScring = hogehogeという書き方かな?

3.(4/4)知られざるJavaScriptの世界 - 知られざるJavaScriptの世界:ITproに、

下記のように定義してもnew Hogeした時には反映されないと書いてあったが理由がよくわからない。

Hoge.foo = function{
  aleart("hogehoge");
 }

*1:ちょっと省略してます