使用原型继承创建 Child Class 的方法时出现“.. 不是函数”错误
".. is not a function" Error when creating a method of Child Class using prototype inheritance
我正在学习 JavaScript 原型制作。这里的 Employee 是父级,我在我的 Programmer 原型中继承了它,但是当我尝试 运行 我的子原型(即 Programmer)的 favoriteLanguage 方法时,它表明 favoriteLanguage 不是一个函数。我尝试阅读 Mozilla 文档,但我无法理解这些内容是否相关!谁能用简单的术语帮助我!
编辑:我知道我可以使用 class,但我想了解为什么它在这种情况下不起作用!
代码如下:
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 有一种更简单的方法来定义构造函数及其分配给新实例的原型: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
属性 定义了 new X
将要使用的对象分配新对象等),但使用起来要简单得多,尤其是在继承时。现在也支持私有字段和方法;以下三项提案均已登陆规范:
在没有这些的情况下拥有真正的私人信息是可能的,但要麻烦得多。
我正在学习 JavaScript 原型制作。这里的 Employee 是父级,我在我的 Programmer 原型中继承了它,但是当我尝试 运行 我的子原型(即 Programmer)的 favoriteLanguage 方法时,它表明 favoriteLanguage 不是一个函数。我尝试阅读 Mozilla 文档,但我无法理解这些内容是否相关!谁能用简单的术语帮助我!
编辑:我知道我可以使用 class,但我想了解为什么它在这种情况下不起作用!
代码如下:
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 有一种更简单的方法来定义构造函数及其分配给新实例的原型: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
属性 定义了 new X
将要使用的对象分配新对象等),但使用起来要简单得多,尤其是在继承时。现在也支持私有字段和方法;以下三项提案均已登陆规范:
在没有这些的情况下拥有真正的私人信息是可能的,但要麻烦得多。