javascript - ".. is not a function"使用原型(prototype)继承创建子类方法时出错

标签 javascript prototype

我正在学习 JavaScript 原型(prototype)设计。这里 Employee 是父级,我在我的程序员原型(prototype)中继承了它,但是当我尝试运行我的子原型(prototype)(即程序员)的 favoriteLanguage 方法时,它显示 favoriteLanguage 不是一个函数。我尝试阅读 Mozilla 文档,但我无法理解这些内容是否相关!任何人都可以用简单的语言帮助我吗?

编辑:我知道我可以使用类,但我想了解为什么它在这种情况下不起作用!

代码如下:

function Employee(givenName, givenExperience, givenDivision){
    this.name = givenName;
    this.experience = givenExperience;
    this.division = givenDivision;
}

Employee.prototype.slogan=function(){
    return `I am ${this.name} and this company is the best`;
}

Employee.prototype.joiningYear=function(){
    return 2020 - this.experience;
}

function Programmer(givenName, givenExperience, givenDivision, language, github){
    Employee.call(this,givenName, givenExperience, givenDivision);
    this.language = language;
    this.github = github;
}

Programmer.prototype.favoriteLanguage = function(){   //Error part
    if (this.language == 'python'){
        return 'Python';
    }
    else{
        return 'JavaScript';
    }
}

Programmer.prototype = Object.create(Employee.prototype);
Programmer.prototype.constructor = Programmer;

//Object.setPrototypeOf(Programmer.prototype, Employee.prototype);

let arju = new Programmer("Arju Aman",0,"Developer","javaScript","arjuaman");

console.log(arju);
// console.log(arju.joiningYear());
// console.log(arju.slogan());

console.log(arju.favoriteLanguage());   //called here

最佳答案

问题是您正在向默认的 Programmer.prototype 对象添加属性:

Programmer.prototype.favoriteLanguage = function(){
    // ...
}

...但片刻之后,您将用一个新对象完全替换该对象:

Programmer.prototype = Object.create(Employee.prototype);

新对象不会具有您添加到旧对象的属性。

要修复此问题,只需将 Programmer.prototype = 语句移至向其添加属性的语句上方即可:

function Employee(givenName, givenExperience, givenDivision){
    this.name = givenName;
    this.experience = givenExperience;
    this.division = givenDivision;
}

Employee.prototype.slogan=function(){
    return `I am ${this.name} and this company is the best`;
}

Employee.prototype.joiningYear=function(){
    return 2020 - this.experience;
}

function Programmer(givenName, givenExperience, givenDivision, language, github){
    Employee.call(this,givenName, givenExperience, givenDivision);
    this.language = language;
    this.github = github;
}

// *** Moved
Programmer.prototype = Object.create(Employee.prototype);
Programmer.prototype.constructor = Programmer;

Programmer.prototype.favoriteLanguage = function(){
    if (this.language == 'python'){
        return 'Python';
    }
    else{
        return 'JavaScript';
    }
}

let arju = new Programmer("Arju Aman",0,"Developer","javaScript","arjuaman");

console.log(arju);

console.log(arju.favoriteLanguage());

但是,您提到您正在学习 JavaScript。自 2015 年以来,JavaScript 有了一种更简单的方法来定义构造函数及其分配给新实例的原型(prototype):class 语法:

class Employee {
    constructor(givenName, givenExperience, givenDivision) {
        this.name = givenName;
        this.experience = givenExperience;
        this.division = givenDivision;
    }

    slogan() {
        return `I am ${this.name} and this company is the best`;
    }

    joiningYear() {
        return 2020 - this.experience;
    }
}

class Programmer extends Employee {
    constructor(givenName, givenExperience, givenDivision, language, github) {
        super(givenName, givenExperience, givenDivision);
        this.language = language;
        this.github = github;
    }

    favoriteLanguage() {
        if (this.language == "python"){
            return "Python";
        } else{
            return "JavaScript";
        }
    }
}

let arju = new Programmer("Arju Aman", 0, "Developer", "javaScript", "arjuaman");

console.log(arju);

console.log(arju.favoriteLanguage());

新语法仍然做很多相同的事情(这仍然是原型(prototype)继承,它仍然创建一个带有 prototype 属性的构造函数,该属性定义 new X 的对象将分配新对象等),但使用起来更简单,特别是在继承时。现在还支持私有(private)字段和方法;以下三个提案均已纳入规范:

没有这些,拥有真正的私有(private)信息是可能的,但要麻烦得多。

关于javascript - ".. is not a function"使用原型(prototype)继承创建子类方法时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67704764/

相关文章:

JavaScript:扩展 Array.prototype 有什么危险?

Javascript从父类中定义的继承类方法访问类变量

javascript - 如何正确等待 ES6 Javascript 异步函数的解析值?

javascript - 草稿状态/在 Angular 2 中保存时发布更改

oop - 在函数式编程中实现多态性

javascript - 如果我们创建新的原型(prototype)属性,对象会改变它的隐藏类吗?

javascript - [].slice 或 Array.prototype.slice

javascript - 比较 2 个数组以查看对象是否存在

javascript - 在日期选择器上显示特定月份而不更改所选日期

javascript - 在下拉项的 anchor 标记中使用输入类型文件