物件導向程式設計(OOP)已經存在多年
物件是一種在邏輯上與一群資料及功能有關的東西
它的設計,是為了對應我們對這個世界的理解方式
引用: JavaScript 學習手冊
ES6
之後我們能用簡潔的方式定義類別
class Car {
constructor() {
//
}
}
// 建立實例
const car1 = new Car()
const car2 = new Car()
console.log(car1 instanceof Car) // true
console.log(car2 instanceof Car) // true
console.log(car1 == car2) // false
說明
範例中定義了Car
類別,接著定義兩個實例
car1, car2
接著我們使用instanceof
驗證該實例
屬於Car類別
最後我們測是兩個Car實例
是否相等,結果不相等
物件永遠不相等
class Person {
constructor(name, age) {
this.name = name
this.age = age
this.height = '165cm'
}
say(content) {
console.log(content)
}
}
// 建立實例
const Peter = new Person('Peter', 20)
console.log(Peter)
// [object Object] {
// age: 20,
// height: "165cm",
// name: "Peter"
// }
Peter.height = '170cm'
console.log(Peter.height) // "170cm"
Peter.say('Hello') // "Hello"
說明
建立實例
後我們能夠輕易地修改屬性來更改狀態
所有的方法
都會是該實例
的prototype
靜態方法
是執行與整個類別有關的工作,而不是針對實例
class Person {
constructor(name, age) {
this.name = name
this.age = age
this.idNumber = undefined
}
static generateIdNumber() {
let idNumber = ''
const texts = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
for (let i = 0; i < 10; i++)
idNumber += texts.charAt(Math.floor(Math.random() * texts.length))
return idNumber
}
}
const Sam = new Person('Sam', 1)
Sam.idNumber = Person.generateIdNumber()
console.log(Sam)
// [object Object] {
// age: 1,
// idNumber: "7OFL1VSJ5N",
// name: "Sam"
// }
說明
當PersonSam出生時我們使用大家通用的生份正規則來產生idNumber
由於全國人民的身分證產生規則都一樣,因此generateIdNumber
方法屬於Person類別
而非實例
Sam
類別
是有階層之分的,例如汽車與機車屬於交通工具;狗與貓屬於動物
當有階層之分時我們就能夠透過繼承
來將共通特性抽離至父類別
class Transportation {
constructor() {
this.passengers = []
this.maxPassengers = 2
}
addPassenger(person) {
if(this.passengers.length == this.maxPassengers) {
console.warn('too much person.')
} else {
this.passengers.push(person)
}
return this.passengers
}
}
class Car extends Transportation {
constructor() {
super()
this.maxPassengers = 4
}
}
class Autobike extends Transportation {
constructor() {
super()
this.maxPassengers = 2
}
}
const myCar = new Car()
console.log(myCar.constructor.name) // Cart
console.log(myCar instanceof Transportation) // true
const myBike = new Autobike()
console.log(myBike.constructor.name) // Autobike
console.log(myBike instanceof Transportation) // true
console.log(myCar.addPassenger('a')) // ["a"]
console.log(myCar.addPassenger('b')) // ["a", "b"]
console.log(myCar.addPassenger('d')) // ["a", "b", "d"]
console.log(myCar.addPassenger('e')) // ["a", "b", "d", "e"]
console.log(myCar.addPassenger('f')) // "too much person."
// ["a", "b", "d", "e"]
console.log(myBike.addPassenger('a')) // ["a"]
console.log(myBike.addPassenger('b')) // ["a", "b"]
console.log(myBike.addPassenger('c')) // "too much person."
// ["a", "b"]
說明
範例中Car與Autobike都可以增加乘客
因此我們把addPassenger定義於Transportation
但由於不同的交通工具乘客成載量並不相同,因此在子類別建構是中複寫父類別
的屬性值
我們能夠在子類別
的建構子constructor
中使用super
來繼曾父類別
的建構子constructor
接著在子類別中定自己的屬性,而若屬性已經定義於父類別則會蓋過父類別
的屬性
因此我們可以針對不同的子類別
定義相同屬性但卻不同數值來因應現實環境的需求
父類別
有時亦被稱為超類別
更完整的物件操作請參考MDN JavaScript 物件導向介紹