2017-07-29 99 views
0

我正在學習Javascript中的原型繼承,並且試圖編寫一個從子方法的原型調用父方法的示例。但是,我沒有得到我預期的結果。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類有nameagegreeting方法附加到它的原型打印一些數據。 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 

我知道()調用方法需要與一起傳遞參數上下文this。它的名稱是this (Person),它被替換爲名稱,它告訴我這些類不是純粹繼承的,因爲我在調用裏面的方法。我應該可以在裏面使用super.methodName(),但超級在這裏不起作用。

請告訴我,我所做的是如何實現JS的繼承或如果我做錯了什麼。

PS:我試圖用一個超級呼叫問候像Java編寫,但它給了我一個錯誤。這是否意味着Employee類沒有擴展Person類?

+0

重命名屬性'this.name'在'Person',它與'函數衝突。名稱的財產。 – Teemu

回答

1
Employee.prototype = Object.create(Person) 

分配Employee.prototypePerson功能。 函數具有name屬性,這就是爲什麼它記錄了該特定函數的名稱:Person

Employee實例有三個池,它可以尋找性質:

首先是有3個屬性Employee實例:

  1. 年齡
  2. 工資

其次是Employee原型(如果在Employee實例上找不到prop,js l這裏ooks),有1種方法:

  1. 問候

三是人物原型(如果prop不是以前的對象發現,JS看這裏),有1種方法:

  1. 問候

由於greeting既是對Employee.prototypePerson.prototype,你不能ACC來自Employee實例的ess 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的一個實例)

+0

我已經將Object.create(Person)''改爲'Object.create(Person.prototype)'。這是正確的,還是總是用'Object.create(Person)'來啓用繼承? – v1shnu

+0

@ v1shnu它應該是Object.create(Person.prototype)'。你已經改變了你的答案中的代碼(它會返回你想要的),所以我沒有將它包含在我的答案中以求簡潔。 – marzelin

+0

我想知道爲什麼'Person.prototype.greeting.call(this)'用於調用父類方法。如果啓用了繼承,那麼它是不是應該直接調用?如果我已經將其設置在Employee函數的第一行,爲什麼我應該在調用方法中再次傳遞'this'。 – v1shnu