【问题标题】:Properties inside method showing undefined but working outside the methods . How to fix it?方法内部的属性显示未定义但在方法之外工作。如何解决?
【发布时间】:2021-11-08 14:56:06
【问题描述】:

在下面的代码中,当我执行 console.log(teacher1.getDetails());属性值显示未定义,但是当我执行 console.log(teacher1.personName) 或 console.log(teacher.mainSubject) 时,它显示属性值。这里发生了什么?我错过了什么?有人可以解释一下吗?以及如何让它发挥作用?

let Person = function(personName, age) {
  this.personName = personName;
  this.age = age;
};

Person.prototype.getDetails = function() {
  return `Person Name:${this.personName}. Age is ${this.age}.`;
};

//Child constructor function
let Teacher = function(personName, age, mainSubject) {
  Person.call(this, personName, age);
  this.mainSubject = mainSubject;
};
Teacher.prototype = Object.create(Person.prototype); //inheritance
Teacher.prototype.getDetails = function() {
  return `${this.__proto__.getDetails()} Main subject is ${this.mainSubject}.`; //optionally invoke the parent method.
};

let teacher1 = new Teacher("Sakib", 35, "Physics");
console.log(teacher1.getDetails()); //invokes Teacher.getDetails() method (child's method).

【问题讨论】:

    标签: javascript inheritance


    【解决方案1】:

    你需要像这样在 Teacher 类中实现 getDetails 方法:

    Teacher.prototype.getDetails = function() {
        return `${Person.prototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`;
    }
    

    由于下一个,您的实现不起作用:您调用有关父上下文的父方法,该上下文没有定义值,因为在教师构造函数中您定义了有关子上下文的值。

    Person.call(this, personName, age);
    

    工作示例:

    let Person = function(personName, age) {
      this.personName = personName;
      this.age = age;
    };
    
    Person.prototype.getDetails = function() {
      return `Person Name:${this.personName}. Age is ${this.age}.`;
    };
    
    //Child constructor function
    let Teacher = function(personName, age, mainSubject) {
      Person.call(this, personName, age);
      this.mainSubject = mainSubject;
    };
    Teacher.prototype = Object.create(Person.prototype); //inheritance
    Teacher.prototype.getDetails = function() {
      return `${Person.prototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`; //optionally invoke the parent method.
    };
    
    let teacher1 = new Teacher("Sakib", 35, "Physics");
    console.log(teacher1.getDetails()); //invokes Teacher.getDetails() method (child's method).

    【讨论】:

    • 谢谢。这行得通。但我仍然不知道它是如何工作的。你能给我一些关于这方面的阅读材料吗?你真是太好了。
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案2】:

    代码中的问题:

    • this.__proto__.getDetails() 不直接调用Person.prototype 中定义的getDetails 函数,因为在getDetails() 函数的第一次调用中,this.__proto__ 返回Teacher.prototype。结果,this.__proto__.getDetails() 调用自己,即Teacher.prototype.getDetails()

      第二次调用Teacher.prototype.getDetails() 时,this.__proto__ 现在指代Person.prototype,因为this 现在是Teacher.prototype,它的原型是Person.prototype

      Teacher.prototype.getDetails() 的第二次调用调用Person.prototype.getDetails() 函数

    • 您需要绑定this 以确保Person.prototype.getDetails()this 的值正确

    • 您不应该使用__proto__ - 它已被弃用。使用Object.getPrototypeOf()获取对象的原型

    固定代码:

    let Person = function(personName, age) {
      this.personName = personName;
      this.age = age;
    };
    
    Person.prototype.getDetails = function() {
      return `Person Name:${this.personName}. Age is ${this.age}.`;
    };
    
    let Teacher = function(personName, age, mainSubject) {
      Person.call(this, personName, age);
      this.mainSubject = mainSubject;
    };
    
    Teacher.prototype = Object.create(Person.prototype);
    Teacher.prototype.constructor = Teacher;
    
    Teacher.prototype.getDetails = function() {
      const personPrototype = Object.getPrototypeOf(Object.getPrototypeOf(this));
      return `${personPrototype.getDetails.call(this)} Main subject is ${this.mainSubject}.`;
    };
    
    let teacher1 = new Teacher("Sakib", 35, "Physics");
    console.log(teacher1.getDetails());

    【讨论】:

    • 我从教程中学习了代码,其中父子构造函数的属性都是预定义的。我试图使其动态化并将属性值作为 arguments/parameters 提供。教程中的代码有效,但我的没有。你解释的方式,对我很有帮助。非常感谢。
    猜你喜欢
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-10
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多