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 questionthis阅读更多关于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是因为thisfoo方法是prototype,并且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}

第二个是当你从里面调用它时B,你可以看到msg它不存在。

于 2013-03-28T17:45:45.870 回答