2011-08-12 12 views
1

私は本でJavaScriptを再生しますウェブデベロッパーのためのプロフェッショナルJavaScript。私は6.2.6節の例を練習します。コードは次のとおりです。Javascript:[ユーザー定義のプロトタイプ]からの変数は利用できません

function creatPrototype(subType, superType) 
{ 
    function subTypePrototype(){}; 
    subTypePrototype.prototype = superType.prototype; 
    subTypePrototype.constructor = subType; 
    subTypePrototype.str = "say"; 
    return new subTypePrototype(); 
} 

function Person(name, age) 
{ 
    this.name = name; 
    this.age = age; 
} 
Person.prototype.say = function(){ 
    writeln("bill say"); 
} 


function itMan(name, age){ 
    Person.apply(this, arguments); 
} 
itMan.prototype = creatPrototype(itMan, Person); 


var Bill = new itMan("bill", 25); 

writeln(itMan.prototype.str); //expect "say" 
writeln(Person.prototype == itMan.prototype.prototype); //expect true 
Bill.say(); //expect "bill say" 

結果は次のとおりです。

未定義

法案を

なぜ言いますか?

  1. itMan.prototype.strは

  2. Person.prototypeを "言う" と仮定されてとitMan.prototype.prototypeが同じオブジェクト

  3. Bill.sayを指す必要があります( )正しく実行されるので、プロトタイプチェーンはOKです。コードといくつかの誤りがありました

答えて

2

あなたは、プロパティがコンストラクタ関数に属する程度とインスタンスに属する1考える必要があります。 prototypeは関数のプロパティですが、constructorstrは両方ともインスタンスのプロパティである必要があります。

これはそれを行う必要があります。

function createPrototype(subType, superType) 
{ 
    function subTypePrototype(){}; 
    subTypePrototype.prototype = superType.prototype; 

    var newPrototype = new subTypePrototype(); 

    newPrototype.constructor = subType; 
    newPrototype.str = "say"; 
    return newPrototype; 
} 

しかし、あなたはまた、subTypeをpassongているとして、あなたが実際に直接プロトタイプ割り当てることができます。

function inherit(subType, superType) 
{ 
    function tconstr(){}; 
    tconstr.prototype = superType.prototype; 

    subType.prototype = new tconstr(); 

    subType.prototype.constructor = subType; 
    subType.prototype.str = "say"; 
} 

をしてからちょうど

inherits(itMan, Person); 
でそれを呼び出すに

Person.prototypeとitMan.prototype.prototypeは、同じオブジェクトを

を指している必要がありprototype機能のではなく、オブジェクトのプロパティであることを覚えておいてください。しかし、itMan.prototypeが対象です。明示的にオブジェクトプロトタイプを参照しない限り、オブジェクトプロトタイプにアクセスすることはできません(しかし、そうしません)。

のECMAScript 5で

Object.getPrototypeOf[MDN]を使用して、プロトタイプを取得する方法があります。これは新しいブラウザーでしか動作しません。ここで

はあなたのコードのworking exampleです。

+0

あなたはポイントを持っています。あなたのソリューションは**本の**の元の例に似ています。 _subTypePrototype。constructor_とstrは戻り値の一部ではないかもしれません_new subTypePrototype()_。 – delai

1

、あなたのコードでは

function creatPrototype(subType, superType) 
{ 
    function subTypePrototype(){ 
    this.prototype = superType.prototype; 
    this.constructor = subType; 
    this.str = "say"; 
} 


    return new subTypePrototype(); 
} 

function Person(name, age) 
{ 
    this.name = name; 
    this.age = age; 
} 
Person.prototype.say = function(){ 
    document.writeln("bill say"); 
} 


function itMan(name, age){ 
    Person.apply(this, arguments); 
} 
itMan.prototype = creatPrototype(itMan, Person); 


var Bill = new itMan("bill", 25); 

document.writeln(itMan.prototype.str); //expect "say" 

document.writeln(Person.prototype == itMan.prototype.prototype); //expect true 
Bill.prototype.say(); //expect "bill say" 

このコードを試してみてください、あなたはそうthisオブジェクトを使用していなかったitMAnあなたは subTypePrototype.constructor = subType; を使用していた 、何の変数strを持っていないし、 subTypePrototype.prototype = superType.prototype; したがってBill.sayが動作していて、Person.prototype == itMan.prototype.prototypeが機能していませんでした。

+0

あなたのアプローチが優れているが、this' 'に' prototype'と 'constructor'を割り当てることは間違っています。 –

+0

Felixがこれを正しく示しています。正しく実行する方法の例です。アウトpoiningため –

+0

@felixありがとう、あなたはあなたの方法は、あなたがプロトタイプを使用しないように彼に言っている、だから、正しいもの – Ankur

0

プロトタイプは予約キーワードであり、あなたは Articles on prototype keyword

あなたはあなたのコード内のいくつかの問題を持って、それを使用しながら、非常に注意する必要があります。

return new subTypePrototype(); 

あなたは関数を作成し、その後、あなたは

return subTypePrototype; 

しかし、あなたがすべきのようなあなたの関数へのポインタを返す必要があります実行された機能の結果を返すされています。そして、あなたのcreateSubPrototype内

親の "プロトタイプ"を取得したいと思われるため、関数を作成しないようにしてください:)

本当にあなたのコードはもっと似ているはずです:

function createPrototype(subType, superType) 
{ 
    subTypePrototype = superType.prototype; 
    subTypePrototype.constructor = subType; //- beware this is wrong !!! 
    subTypePrototype.str = "say"; 
    return subTypePrototype; 
} 

あなたがサブ&親の型にそれを行う方法

両方更新しているそうすることによって、私はのように間違ってマークされている行を確認してください:あなたがオブジェクトを拡張したい場合、私は助言言われていること をあなたは既存のライブラリを使用する。 (jQuery、Mootoolsなど)。Here a sample on how to do it properly

+0

で、正しく、まだあなたのリンクは、プロトタイプのキーワードを使用する方法を示し記事にありますか?プロトタイプの使用には何も問題はありません。実際には、JavaScriptの継承を達成するための適切な方法です(少なくともDouglas Crockford http://javascript.crockford.com/prototypal.htmlを参照)。 – RoccoC5

+0

私はあなたを失望する必要がありますが、 'prototype'は予約キーワードではありません:http://ecma262-5.com/ELS5_HTML.htm#Section_7.6.1 –

+0

はあなた' creatPrototype'も同様に修正されていません。 'subTypePrototype'に割り当てたプロパティは' superType.prototype'にも割り当てられます。これは良いアプローチではありません。 –

関連する問題