在子类中未定义javascript类成员

时间:2013-03-28 17:41:09

标签: javascript class inheritance

这是我的代码,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 个答案:

答案 0 :(得分: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 question

的javascript中详细了解this的工作原理

答案 1 :(得分: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);
}

答案 2 :(得分: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它也是一个好的开始,即使它有点旧。

答案 3 :(得分:0)

您刚刚调用了A.prototype.foo函数,因此msg不存在。以下是console.log(this)

A.prototype.foo时控制台的输出
A {msg: "meuahah", foo: function}
A {foo: function}

第二个是从B内部调用它,因为您可以看到msg不存在。