对象未在javascript中调用子类函数

对象未在javascript中调用子类函数,javascript,inheritance,Javascript,Inheritance,我已经用Javascript创建了一个类模型。我将基类的对象传递给子类,以便重写其属性。但当我通过实例化子类来调用函数时,它仍然调用基类函数。我认为它应该调用一个子类函数。下面是代码 function BaseClass(name,lastName){ this.name = name; this.lastName = lastName; } BaseClass.prototype.getName = function() { return this.name; } Base

我已经用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();

我认为现在发生的是,在这方面:

ChildClass.prototype = new BaseClass(name,LastName);
ChildClass.prototype = new BaseClass(name,LastName);
基本上,您正在使用
新的基类()
覆盖
ChildClass
prototype
属性。那么上一行呢

ChildClass.prototype.saveName = ...
这是无效的。要在JavaScript中构建继承机制,请查看或从许多可用库中选择一个。
或者,在这种特定的简单情况下,尝试交换上面两行的顺序。

您的继承模型存在问题。您可能会发现使用或更容易对这样的事情建模

我已经为您对此进行了建模:

类型脚本:

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();
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();
JavaScript(TS编译器输出):

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();
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();

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

在这一行:

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

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

function ChildClass(name, lastName){ // parameters should be declared
  BaseClass.call(this, name, lastName); // call the base class
}
通过使用第一个参数
this
调用基类,基本上运行了基类函数的代码,其中
this
是ChildClass的新实例。基类中的代码已经设置了
childClass.name
childClass.lastName
属性,因此不需要在childClass中这样做

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

ChildClass.prototype = Object.create(BaseClass.prototype);
请注意,您不会从基类实例继承它们,因为您不知道应该使用哪些参数调用构造函数,并且不使用参数调用构造函数并不总是正确的

最后一件事,确保行设置
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();

谢谢你的解释。我将遵循这个模型来研究它。它实际上是有效的。但我也在寻找类似多态性的概念。再次感谢。@Java_新手很乐意帮忙。实际上,多态性问题听起来是个有趣的问题。我对此有一些想法,如果你遇到其他问题,我很乐意与你分享。