对象不是在javascript中调用子类函数

时间:2014-01-15 10:36:33

标签: javascript inheritance

我在Javascript中创建了一个类模型。我将基类的对象传递给子类,以便我可以覆盖其属性。但是当我通过实例化子类来调用函数时,它仍然会调用基类函数。我认为应该调用子类函数。以下是代码。

function BaseClass(name,lastName){
  this.name = name;
  this.lastName = lastName;   
}

BaseClass.prototype.getName = function() {
  return this.name;
}
BaseClass.prototype.getLastName = function() {
  return this.lastName;
}
BaseClass.prototype.saveName = function() {
  console.log("In base class function.");
}

function ChildClass(){
  this.name = this.getName();
  this.lastName = this.getLastName();
}
ChildClass.prototype.saveName = function() {
  console.log("In child class function.");    
}

ChildClass.prototype = new BaseClass(name,LastName);
var childClass = new ChildClass();
childClass.saveName();

3 个答案:

答案 0 :(得分:1)

我认为正在发生的事情是:

ChildClass.prototype = new BaseClass(name,LastName);

您基本上会使用prototype覆盖ChildClass的{​​{1}}属性。所以前一行

new BaseClass()

无效。要在JavaScript中构建继承机制,请查看this guide或许多可用库中的一个。 或者,在这个特定的简单情况下,尝试交换上面两行的顺序。

答案 1 :(得分:1)

您的继承模型存在问题。您可能会发现使用TypeScriptDart

对这类内容进行建模更加容易

我已经为你建模了这个:

<强>打字稿:

class BaseClass {
    constructor(private name: string, private lastName: string) {
    }

    public getName(): string {
        return this.name;
    }

    public getLastName(): string {
        return this.lastName;
    }

    public saveName(): void {
        console.log("In base class function");
    }
}

class ChildClass extends BaseClass {
    public saveName(): void {
        console.log("In child class function");
    }
}

var childClass = new ChildClass("John", "Smith");
childClass.saveName();

JavaScript(TS编译器输出):

var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var BaseClass = (function () {
    function BaseClass(name, lastName) {
        this.name = name;
        this.lastName = lastName;
    }
    BaseClass.prototype.getName = function () {
        return this.name;
    };

    BaseClass.prototype.getLastName = function () {
        return this.lastName;
    };

    BaseClass.prototype.saveName = function () {
        console.log("In base class function");
    };
    return BaseClass;
})();

var ChildClass = (function (_super) {
    __extends(ChildClass, _super);
    function ChildClass() {
        _super.apply(this, arguments);
    }
    ChildClass.prototype.saveName = function () {
        console.log("In child class function");
    };
    return ChildClass;
})(BaseClass);

var childClass = new ChildClass("John", "Smith");
childClass.saveName();

TypeScript Playground

上游戏

答案 2 :(得分:0)

正如提到的其他答案一样,继承模型存在重大问题。

在这一行:

ChildClass.prototype = new BaseClass(name,LastName);

nameLastName可能未定义,因为您正在全局范围(或​​您定义类的范围)中查找它们。它们与作为参数传递给ChildClass的构造函数的内容完全没有关系。

相反,您希望从子构造函数中调用基类构造函数,如下所示:

function ChildClass(name, lastName){ // parameters should be declared
  BaseClass.call(this, name, lastName); // call the base class
}

通过使用第一个参数this调用BaseClass,您基本上运行了BaseClass函数的代码,this是ChildClass的新实例。 BaseClass中的代码设置了childClass.namechildClass.lastName属性,因此您无需在ChildClass中执行此操作。

要完成继承模型,还需要从基类的原型继承方法:

ChildClass.prototype = Object.create(BaseClass.prototype);

请注意,您不会从BaseClass的实例继承它们,因为您不知道应该使用哪些参数来调用构造函数,并且在没有参数的情况下调用它并不总是正确的。

最后一点,确保行设置ChildClass.prototype 之前 ChildClass.prototype上定义的任何方法/属性,否则您只需覆盖它。

完整代码:

//===== BaseClass
function BaseClass(name,lastName){
  this.name = name;
  this.lastName = lastName;   
}

BaseClass.prototype.getName = function() {
  return this.name;
}
BaseClass.prototype.getLastName = function() {
  return this.lastName;
}
BaseClass.prototype.saveName = function() {
  console.log("In base class function.");
}

//======= ChildClass
function ChildClass(name, lastName, age){
  BaseClass.call(this, name, lastName);
  this.age = age;
}
ChildClass.prototype = Object.create(BaseClass.prototype);

ChildClass.prototype.saveName = function() {
  console.log("In child class function.", this.name, this.lastName, this.age);    
}

//=========== usage
var childClass = new ChildClass('john', 'doe');
childClass.saveName();