今天要來看一下在JavaScript中的Inheritance(繼承)概念。繼承的概念在需要重複建立具備特定的屬性或方法的物件時,免除物件和屬性的重複宣告,Day4的內容在說明原型鏈的時候有提到原型繼承(prototypal inheritance),是在JavaScript語法中使用到的繼承方法,但今天的重點會放在NodeJS提供另外的Object繼承方法與補充Class(ES6)的繼承語法,以下會分別說明。
繼承是指某個物件(子物件)得到另一個物件(母物件)屬性的行為,子物件在繼承母物件時,會使子物件含有母物件的屬性,但是不會複製母物件的屬性值。以中秋節的伴手禮月餅來舉例,假設今天說的子物件是「月餅」,另外假設母物件是「蛋黃酥」,會有:蛋黃來源、餡料口味的屬性,如果確定前面說的「月餅」是「蛋黃酥」的話,就會繼承「蛋黃酥」的蛋黃來源和餡料口味的屬性,而蛋黃來源和餡料口味是要依據拿到的「月餅」去定義內容的。
在Object(物件)的建立方法,除了Day4提到的建構函數(constructor)外,另外可以使用Object.create()
方法,透過一個已經定義完成的物件建立新的物件,Object.create()
方法會將定義完成的物件作為新物件的原型(prototype)以建立新物件。
NodeJS的util
Module中,所具備的inherits
函式就是以Object.create()
的方法進行繼承,假定A物件為子物件、B物件為母物件,透過util.inherits(A,B)
,會以B物件的原型為參數建立一個A物件的原型,以讓兩個物件具備原型繼承的關係。
實作看看:以EventEmitter為例
- 引入
util
與events
Module。let util = require("util"); let EventEmitter = require("events");
- 定義一個具備
firstName
、lastName
與greeting
屬性且名為Person
的新物件,並繼承events
。function Person(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; this.greeting = "Hello, " + this.firstName +this.lastName; } util.inherits(Person, EventEmitter);
- 在
Person
物件的原型中加入greet
方法,並在方法中加入greetTime
事件的觸發動作。Person.prototype.greet = function(){ console.log(this.greeting); this.emit("greetTime"); }
- 建立一個
Person
新物件、註冊greetTime
事件,並呼叫greet
。let chwk = new Person("chw","k"); chwk.on("greetTime", function(){ console.log(new Date()); }); chwk.greet();
- 執行除錯後,印出的成果包含原型中定義的
greet
方法所印出的字串及被其中觸發功能所觸發的greetTime
事件所印出的時間字串。
記得Day4有提到ES6標準所帶來的語法糖-Class,在繼承的概念部分也提供了簡潔的語法,透過精簡的extends
就可以直接加上母物件名稱以繼承其屬性,一樣以EventEmitter
為例來看與物件繼承語法的差異。
實作看看:以EventEmitter為例
- 引入
events
Module。let EventEmitter = require("events");
- 定義一個具備
firstName
、lastName
、greeting
屬性及greet
方法的Person
Class,以extends
繼承events
。class Person extends EventEmitter{ constructor(firstName, lastName){ super(); // 在class中的constructor是方法,要使用super()提升至上層以取得this物件屬性 this.firstName = firstName; this.lastName = lastName; this.greeting = "Hello, " + this.firstName + this.lastName; } greet(){ console.log(this.greeting); this.emit("greetTime"); } }
- 建立一個新的
Person
物件、註冊greetTime
事件並呼叫greet
方法。let chwk = new Person("chw", "k"); chwk.on("greetTime", function(){ console.log(new Date()); }); chewk.greet();
- 執行除錯後,印出的成果包含原型中定義的
greet
方法所印出的字串及被其中觸發功能所觸發的greetTime
事件所印出的時間字串。
繼承的概念讓物件得以使用其他已定義好的物件數性及方法,減少重複定義方法及物件,使物件的建立更加快速、簡便。
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/super
Learn and Understand NodeJS [課程]