1

これが私のコードです。クラス B はクラス A を継承します。

function A() {
    this.msg = 'meuahah';
    A.prototype.foo = function() {
        alert(this.msg);
    }
}

function B() {
    A.call(this);
    B.prototype.bar = function() {
        A.prototype.foo();
    }
}

a = new A();
a.foo(); // alerts 'meuahah'
b = new B();
b.bar(); // alerts 'undefined'

b.bar() が「meuahah」を表示しないのはなぜですか?

4

4 に答える 4

2

thisその場合、グローバル オブジェクトにバインドされるためです。

この関数を呼び出しています

function() {
        alert(this.msg);
    }

オブジェクトにバインドされていない場合。そのthisため、(ブラウザーにある) グローバル オブジェクトを参照しwindow、プロパティを持たないため、msg未定義のアラートが表示されます。

呼び出すときにa = new A()、新しいオブジェクトを作成し、プロパティとして msg を追加し、そのプロトタイプ チェーンに foo() を設定します。したがって、a.foo()foo を呼び出すと、 にバインドされathis参照されaます。

一般的には、おそらくこのように見えるものが必要です。

function A() {
    this.msg = 'meuahah';
}

A.prototype.foo = function() {
    alert(this.msg);
}

function B() {
    A.call(this);
}

B.prototype = Object.create(A.prototype);

B.prototype.bar = function() {
    this.foo();
}

この質問thisから、javascript でどのように機能するかについて詳しく読むことができます

于 2013-03-28T17:44:39.867 に答える
2

あなたのプロトタイプの継承はまったく正しくありません。これはおそらくあなたがやりたいことです:

function A() {
    this.msg = 'meuahah';
}

A.prototype.foo = function() {
    alert(this.msg);
}

function B() {
    A.call(this);
}

B.prototype = new A();
B.prototype.bar = function() {
    this.foo();
}

a = new A();
a.foo(); 
b = new B();
b.bar();

foo次のBようにオーバーライドできます。

B.prototype.foo = function() {
    // Call the original foo method
    A.prototype.foo.apply(this, arguments);
}
于 2013-03-28T17:45:33.143 に答える
2

b.bar表示さundefinedれる理由は、thisメソッドのfooprototypeであり、プロパティprototypeがないためです。msg

基本的に、要点である継承を見逃しています。したがって、ここでコードを再検討します。

function A() {
  this.msg = 'meuahah';
}

A.prototype.foo = function() {
  alert(this.msg);
}

function B() {
    A.call(this);
}

// Set the inheritance! Or better, the prototype's chain,
// so that any instance of B will have methods of A too
B.prototype = Object.create(A.prototype);

B.prototype.bar = function() {
  // Because the inheritance, now B has the A's `foo` method too
  this.foo();
}

// But... We can also override it.
B.prototype.foo = function() {
  // do something
  alert("override");
  // then call the original one
  A.prototype.foo.call(this);
}

オブジェクトとコンストラクターについての理解を深めるのに役立つことを願っています。Object.createについても調査することをお勧めします。これは非常に役立ちます。一般的なES5メソッド。

Working with Objectsの読み物は、たとえ少し古いものであっても、良い出発点です。

于 2013-03-28T17:57:09.147 に答える
0

A.prototype.foo 関数と呼ばれるだけなので、msg存在しません。console.log(this)中に入ったときのコンソールからの出力は次のとおりですA.prototype.foo

A {msg: "meuahah", foo: function}
A {foo: function}

B2 つ目は、 が存在しないことがわかるように、 内から呼び出す場合ですmsg

于 2013-03-28T17:45:45.870 に答える