ECMAScript 5 並沒有 Class,雖然仍然可以使用 new
建立 Object,但必須透過 Constructor Function,但究竟 Constructor Function 有什麼黑魔法,竟然可以使用 new
建立 Object 呢 ?
Version
ECMAScript 5
Constructor Function
let Book = function(title, price) {
this.title = title
this.price = price
}
let book = new Book('FP in JavaScript', 100)
book.title // ?
book.price // ?
Book
為典型 constructor function,使用 CamelCase 命名,因為 this
會指向 Object,因此可透過 this.title
建立 property。
只要使用 new
,就可對 constructor function 傳入 argument 建立 Object。
Function.prototype.call()
let Book = function(title, price) {
this.title = title
this.price = price
}
let book = {}
Book.call(book, 'FP in JavaScript', 100)
book.title // ?
book.price // ?
為什麼使用 new
就能使用 constructor function 建立 Object 呢 ?
第 6 行
let book = {}
Book.call(book, 'FP in JavaScript', 100)
事實上當使用 new
時,相當於以下步驟:
- 先使用
{}
object literal 建立 empty object 給book
- 然後使用
Book.call()
將book
傳進去,因為book
是 Object,所以this
指向book
,在Book()
使用this
新增 property 相當於對book
新增 property
也因為
new
本質是搭配call()
實踐,因此 constructor function 只能使用 function declaration 或 function expression,而不能使用 arrow function
Normal Function
let Book = function(title, price) {
this.title = title
this.price = price
}
let book = Book('FP in JavaScript', 100)
book.title // ?
book.price // ?
若忘記寫 new
,則 Book()
視為普通 function:
Book()
內的this
為undefined
無法執行Book()
沒有 return 值,因此book
為undefined
無法執行
Conclusion
- ES5 因為沒有 class,以前為了使用
new
只好死背 constructor function 格式並使用this
,事實上它是透過call()
傳入 empty object 後,讓this
指向 empty object 再動態新增 property,了解原理後就不必死背了
Reference
許國政, 008 天重新認識 JavaScript