【问题标题】:Inheritance in Javascript - parent method calls from child methodsJavascript中的继承-从子方法调用父方法
【发布时间】:2017-07-29 08:27:28
【问题描述】:

我正在学习 Javascript 中的原型继承,并尝试编写一个从子方法的原型调用父方法的示例。但是,我没有得到我预期的结果。

Person.js

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


Person.prototype.greeting = function() {
    console.log("Hello, My name is " + this.name + " and I am " + this.age + " years old.")
}

module.exports = Person;

Employee.js

var Person = require('./Person');

var Employee = function(name, age, salary) {
    Person.call(this, name, age);
    this.salary = salary;
}

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

Employee.prototype.greeting = function() {
    Person.prototype.greeting.call(this);
    console.log("My salary is " + this.salary)
}

module.exports = Employee;

Test.js

var Person = require('./Person');
var Employee = require('./Employee');

var p = new Person("Rob", 24);

p.greeting();

var e = new Employee("Jim", 25, 1200000);

e.greeting();

所以基本上我拥有的是一个Person 类,它具有nameage 以及一个附加到其原型的greeting 方法,用于打印一些数据。 Employee 类扩展了 Person 并具有附加属性 salary。它还通过打印薪水覆盖greeting 方法。但是,在打印salary 之前,它会调用super class' 问候方法,然后打印salary

我的预期输出是:

Hello, My name is Rob and I am 24 years old.
Hello, My name is Jim and I am 25 years old.
My salary is 1200000

但实际输出是:

Hello, My name is Rob and I am 24 years old.
Hello, My name is Person and I am 25 years old.
My salary is 1200000

我知道 call() 方法需要与上下文 this 一起传递参数。 this (Person) 的名称被替换为表明类不是纯粹继承的名称,因为我在内部调用方法。我应该可以在里面使用super.methodName(),但是 super 在这里不起作用。

请告诉我我所做的是如何实现 JS 中的继承,或者我做错了什么。

PS:我尝试像在 Java 中那样使用 super call 来问候,但它给了我一个错误。这是否意味着 Employee 类没有扩展 Person 类?

【问题讨论】:

  • 重命名Person中的属性this.name,与Function.name属性冲突。

标签: javascript inheritance


【解决方案1】:
Employee.prototype = Object.create(Person)

Employee.prototype 分配给Person 函数。 函数有一个name 属性,这就是它记录该特定函数名称的原因:Person

Employee 实例具有三个可以查找属性的池:

首先是具有 3 个属性的 Employee 实例:

  1. 姓名
  2. 年龄
  3. 工资

其次是Employee原型(如果在Employee实例上没有找到prop,js看这里)有1个方法:

  1. 问候

第三个是具有1个方法的Person原型(如果在以前的对象上没有找到prop,js看这里):

  1. 问候

由于greeting 位于Employee.prototypePerson.prototype 上,因此您无法从 Employee 实例访问Person.prototype.greeting - 它始终会被链中更近的Employee.prototype.greeting 阻止。这就是为什么在:

Employee.prototype.greeting = function() {
    Person.prototype.greeting.call(this);
    console.log("My salary is " + this.salary)
}

你必须直接调用Person.prototype.greeting(函数内部的this是Employee的一个实例)

【讨论】:

  • 我已将 Object.create(Person) 更改为 Object.create(Person.prototype)。这是正确的还是总是Object.create(Person) 来启用继承?
  • @v1shnu 它应该是Object.create(Person.prototype)。您已将答案中的代码更改为正确的代码(它返回您想要的),因此为简洁起见,我没有将其包含在我的答案中。
  • 我想知道为什么Person.prototype.greeting.call(this)用来调用父类方法。如果启用了继承,那么不应该直接调用它吗?如果我已经在Employee函数的第一行设置了this,为什么还要在call方法中再次传递。
  • @v1shnu 如果直接调用Person.prototype.greeting()this 将指向Person.prototype 而不是类实例。如果你在Employee.prototype.greeting 中调用this.greeting(),它会一次又一次地调用自己。
猜你喜欢
  • 1970-01-01
  • 2017-07-20
  • 2012-01-06
  • 1970-01-01
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2016-08-15
相关资源
最近更新 更多