3

プロトタイプの継承とは何かを理解していますが、実装については混乱している必要があります。関数コンストラクターのプロトタイプを変更すると、そのコンストラクターのすべてのインスタンスに影響すると思いましたが、そうではありません。JSはオブジェクトからそのプロトタイプへのメソッドルックアップをどのように行いますか?

これが例です

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

a = new A("brad");

A.prototype = {
  talk: function(){
    return "hello " + this.name;
  }
}

a.talk() // doesn't work
b = new A("john");
b.talk() // works

のプロトタイプでメソッドをa探すという印象を受けたので、インスタンス化の前後のプロトタイプへの変更は反映されますが、そうではないようです。誰かが私のためにこれを説明できますか?talk()AAa

4

2 に答える 2

4

これは、プロトタイプの変更交換の違いです。

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

a = new A("brad");
// Change, don't replace.
A.prototype.talk = function(){
    return "hello " + this.name;
};

a.talk() // works
b = new A("john");
b.talk() // works

これが起こっていることです:

// Continued from above
var old_proto = A.prototype;

// Nuke that proto
A.prototype = {
talk: function() {
    return "goodbye " + this.name;
}
};

var c = new A("Al");

a.talk() // hello brad
b.talk() // hello john
c.talk() // goodbye Al

old_proto.say_goodbye = function() {
    return "goodbye " + this.name;
};

a.say_goodbye() // goodbye brad
b.say_goodbye() // goodbye john
c.say_goodbye() // TypeError c.say_goodbye is not a function.
于 2011-03-03T18:53:26.010 に答える
3

ショーンの良い答えを支持する:オブジェクトのインスタンスを作成する前にそれを行う限り、プロトタイプ全体を置き換えることに何の問題もありません。これも機能します:

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

A.prototype = {
  talk: function(){
    return "hello " + this.name;
  }
}

a = new A("brad");

a.talk() // works

後で交換しないように注意してください(それがあなたがやろうとしていることでない限り)。

元の例Aでは、最初のインスタンスを作成した時点ではカスタムプロトタイプがありませんでしたが、間にプロトタイプを作成したため、2番目のインスタンスを作成したときにカスタムプロトタイプがありました。

プロトタイプチェーンは、オブジェクトがインスタンス化されるときに確立されるため、同じ「クラス」の2つのインスタンスが異なるプロトタイプを持つ可能性があります。

これはあらゆる種類の問題を引き起こす可能性があります。

var a = new A("brad");
console.log(a instanceof A) // true

A.prototype = {
  talk: function(){
    return "hello " + this.name;
  }
}

console.log(a instanceof A) // false

によって参照されるオブジェクトは、のプロトタイプチェーンにあるかどうかをチェックすることによって機能するためa、のインスタンスとは見なされなくなりました。AinstanceofA.prototypea

于 2011-03-03T19:04:48.077 に答える