JS 原力覺醒 Day20 - 物件

今天要提到 JS 裡面物件的概念,「物件」的概念在 JS 裡面是非常重要的,也是 JS 的基本元素。但是相對於物件導向語言的物件,意義上又有一點不一樣。就像前面提到在 JS 裡面函式也是屬於物件,這樣子的行為在一般物件導向的語言裡面是沒有的。
https://ithelp.ithome.com.tw/upload/images/20190916/20106580lJIWdcHc2t.png

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 的物件是如何透過原型來共用屬性的。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×