iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

學習NodeJS的30天系列 第 6

Day6 JS-Object與Inheritance

今天要來看一下在JavaScript中的Inheritance(繼承)概念。繼承的概念在需要重複建立具備特定的屬性或方法的物件時,免除物件和屬性的重複宣告,Day4的內容在說明原型鏈的時候有提到原型繼承(prototypal inheritance),是在JavaScript語法中使用到的繼承方法,但今天的重點會放在NodeJS提供另外的Object繼承方法與補充Class(ES6)的繼承語法,以下會分別說明。

Inheritance 繼承

繼承是指某個物件(子物件)得到另一個物件(母物件)屬性的行為,子物件在繼承母物件時,會使子物件含有母物件的屬性,但是不會複製母物件的屬性值。以中秋節的伴手禮月餅來舉例,假設今天說的子物件是「月餅」,另外假設母物件是「蛋黃酥」,會有:蛋黃來源、餡料口味的屬性,如果確定前面說的「月餅」是「蛋黃酥」的話,就會繼承「蛋黃酥」的蛋黃來源和餡料口味的屬性,而蛋黃來源和餡料口味是要依據拿到的「月餅」去定義內容的。

https://ithelp.ithome.com.tw/upload/images/20210921/20139980ux4qnDFzNG.jpg

Object的繼承(NodeJS)

在Object(物件)的建立方法,除了Day4提到的建構函數(constructor)外,另外可以使用Object.create()方法,透過一個已經定義完成的物件建立新的物件,Object.create()方法會將定義完成的物件作為新物件的原型(prototype)以建立新物件。

https://ithelp.ithome.com.tw/upload/images/20210921/20139980tdsjb9BbdX.jpg

NodeJS的utilModule中,所具備的inherits函式就是以Object.create()的方法進行繼承,假定A物件為子物件、B物件為母物件,透過util.inherits(A,B),會以B物件的原型為參數建立一個A物件的原型,以讓兩個物件具備原型繼承的關係。

https://ithelp.ithome.com.tw/upload/images/20210921/20139980fjmMeJWZvn.jpg

實作看看:以EventEmitter為例

  1. 引入utileventsModule。
let util = require("util");
let EventEmitter = require("events");
  1. 定義一個具備firstNamelastNamegreeting屬性且名為Person的新物件,並繼承events
function Person(firstName, lastName){
  this.firstName = firstName;
  this.lastName = lastName;
  this.greeting = "Hello, " + this.firstName +this.lastName;
}

util.inherits(Person, EventEmitter);
  1. Person物件的原型中加入greet方法,並在方法中加入greetTime事件的觸發動作。
Person.prototype.greet = function(){
  console.log(this.greeting);
  this.emit("greetTime");
}
  1. 建立一個Person新物件、註冊greetTime事件,並呼叫greet
let chwk = new Person("chw","k");

chwk.on("greetTime", function(){
  console.log(new Date());
});
chwk.greet();
  1. 執行除錯後,印出的成果包含原型中定義的greet方法所印出的字串及被其中觸發功能所觸發的greetTime事件所印出的時間字串。

https://ithelp.ithome.com.tw/upload/images/20210921/20139980vZx8aRgGgr.png

Class(ES6)的繼承

記得Day4有提到ES6標準所帶來的語法糖-Class,在繼承的概念部分也提供了簡潔的語法,透過精簡的extends就可以直接加上母物件名稱以繼承其屬性,一樣以EventEmitter為例來看與物件繼承語法的差異。

實作看看:以EventEmitter為例

  1. 引入eventsModule。
let EventEmitter = require("events");
  1. 定義一個具備firstNamelastNamegreeting屬性及greet方法的PersonClass,以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");
  }
}
  1. 建立一個新的Person物件、註冊greetTime事件並呼叫greet方法。
let chwk = new Person("chw", "k");

chwk.on("greetTime", function(){
  console.log(new Date());
});
chewk.greet();
  1. 執行除錯後,印出的成果包含原型中定義的greet方法所印出的字串及被其中觸發功能所觸發的greetTime事件所印出的時間字串。

https://ithelp.ithome.com.tw/upload/images/20210921/201399809WYpEdXLzI.png

小結

繼承的概念讓物件得以使用其他已定義好的物件數性及方法,減少重複定義方法及物件,使物件的建立更加快速、簡便。

參考資料

https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/super

Learn and Understand NodeJS [課程]


上一篇
Day5 NodeJS-Events和EventEmitter
下一篇
Day7 JS-Callback
系列文
學習NodeJS的30天30

尚未有邦友留言

立即登入留言