今天要提到 JS 裡面物件的概念,「物件」的概念在 JS 裡面是非常重要的,也是 JS 的基本元素。但是相對於物件導向語言的物件,意義上又有一點不一樣。就像前面提到在 JS 裡面函式也是屬於物件,這樣子的行為在一般物件導向的語言裡面是沒有的。
Outline
- JS 的物件
- 創造物件的方式
- 取用物件的方式
- 物件原型導向
JS 的物件
在 JS 裡,物件代表一連串「屬性名稱」與「數值」的組合 ( name-value pair )。這些組合湊在一起就形成了對某件事情的描述,就像一本書有許多資訊像是書名、作者、出版日期ㄧ樣,你可以用 JS 物件輕鬆的表示現實世界的許多物品:
{
title: 'Le Petit Prince',
author:'Antoine de Saint-Exupery',
pages: '331',
...
}
創造物件的方式
最基本的用來創造物件的方式有幾種:
- 物件實字 ( Object Literal )
- 函式建構子
物件實字 ( Object Literal )
物件實字應該是你最長用到的創造物件方式,使用物件實字創造物件的寫法,跟在 API 傳遞、溝通的時候會用到的 JSON 格式長得很像,都是使用大括號逗號來區分屬性,其實我在文章的開頭就已經使用過了:
let object = { propertyName : 'value', ...}
函式建構子 ( Function Constructor )
在許多物件導向語言裡面,因為以類別為主的語言特性,通常是以 class
創造物件藍圖,並搭配使用 new
關鍵字來產生新的物件,這也是物件導向的基本概念。雖然 JS 並不是物件導向的語言,但早期為了吸引那些習慣使用物件導向語言的工程師來使用,也創造了使用 new
關鍵字,屬於自己獨特的產生物件的方式,稱為「函式建構子」,也就是把函式內容視為其他物件導向語言的建構子( constructor ) 來使用:
function book (name,price) {
this.name = name;
this.price = price
}
let starWar = new book('star war', 500)
console.log(starWar) // book {name: "star war", price: 500}
如果你要產生一個空物件,那麼除了物件實字,你也可以透過下面的方式:
let obj = new Object();
這是什麼意思?我們都知道 JS 裡面有一個物件叫做 Object,裡面有很多好用的 API 例如 Object.keys
可以取得物件的所有屬性名,但是根據上面的說明,new
應該要搭配函式來使用才對啊?難道 Object
是函式不成?
是的! 在 JS 裡面 Object 就是一個函式,你可以對他使用 typeof 來驗證這個說法:
typeof Object // function
既然 Object
本身也是函數,那麼這個說法就合理了,至於為什麼 typeof Object
結果不是 Object ,我想那又是另外一個層面的問題了。
取用物件屬性的方式
取用物件有兩種方式:
- 最常見的
.
運算子 - 使用中括號
[]
使用中括號取用物件來取用屬性,因為能夠使用字串的關係,在取用屬性的時候可以比較有彈性:
let user = {
name:'Yoda'
}
user.name // Yoda
user['name'] //Yoda
物件原型導向
雖然許多人在 JavaScript 撰寫物件導向風格的程式碼,但 JS 並不是像 JAVA 或是 C# 那樣物件導向的語言,而相對的,JS 是物件原型導向( Object-Prototype Oriented )的語言,在 JS 裡面的每個物件都有一個可以用來與其他物件共用屬性跟方法,或是進行複製的隱藏屬性 : [[ Prototype ]]
。
這種繼承的行為也稱為原型繼承 ( prototypical inheritance ),相對於其他像是 PHP、JAVA、Python 這種以類別 ( class ) 為基礎的物件導向語言,這算是比較特別的,在後面的章節我會繼續說明 JS 的物件是如何透過原型來共用屬性的。