【JS幼幼班】Step.07 基本語法:物件型別(object、function)


Posted by nancy543 on 2021-08-19

物件型別 Object (物件):

物件簡單來說,就是把一堆有關係的資料全部群組在一起,所組成的集合資料。

特點:

  • 除了是物件型別之外,也是一種複合資料型別。
  • 物件是一堆屬性名(又稱)和的配對,簡稱「鍵值對」。
  • 屬性名(鍵) Key:只能使用字串或是宣告,字串以英文為主,大小寫不限,但不可使用保留字
  • 值 Value:可填入任何型別。而填入的值大致又分為三類,分別為原生值、物件或函數。如果填入的值是原生值物件,它就歸類在「屬性」;但若填入的值是函數,就歸類在「方法」。
  • 鍵值對:寫法是 屬性名:值
  • 物件成員 Member:「屬性」和「方法」通常合稱為物件中的成員。
  • 屬性 Property:物件中可被描述的資訊。
  • 方法 Method:與物件有關的行為或動作。
  • 一個屬性值可以儲存一組到多組的鍵值對
  • 在 JS 引擎轉譯後,會將物件建立在記憶體中,該物件的屬性和方法也會一併存進記憶體中,等到需要取用或修改時,JS 引擎才會指向儲存物件的記憶體位置。
物件成員 可代入的值 值的型別
屬性 原生值 (包含鍵值對) booleannumberstring...等
屬性 物件 (包含鍵值對) object
方法 函數 function

聽起來好抽象,拿車子來當例子吧!

(圖片源自:木棉花官網)

等等,放錯了...下面這個才對!!

由上表,可以清楚看出,車子本身相當於「物件」,而車型是跑車、顏色是紅色、重量1500kg、馬力2000匹等條件就是車子的「屬性」,其中車型就是「屬性名」,跑車就是「」,車型:跑車就是「鍵值對」。而如何啟動、加速、剎車等行為或可作的動作。就是車子的「方法」。

簡單來說,所有的車子通通都具有相同的屬性或方法,只是屬性中的值會因車子不同而有所不同,且方法也會在不同時間執行。


物件宣告 Creating Objects

來個簡單的例子好了!我家成員有爸爸、媽媽、2 個女兒,爸爸名字叫 John、媽媽叫 Mary、女兒分別叫 NancyJuno。該怎麼把它寫成 JavaScript 呢?

1、先建立空物件。

  • 我們常用 constlet 關鍵字來「宣告物件」,首先宣告我家 myFamily 這個變數
  • 然後使用大括號 { }物件成員寫在裡面,注意在右邊的大括號後方需加上分號 ; 來結束該語句。
const myFamily = {};

2、定義物件成員的鍵值對。

  • 建立物件成員:這裡指的是家庭成員(父母和女兒們)。
  • 屬性語法很簡單,就是 屬性名: 值,如 father: 'John'
  • 屬性名指的就是爸爸 father、媽媽 mother、兩個女兒 daughter1daughter2就是家庭成員各自的名字(字串)。
  • 每一組鍵值對之間,要用逗號 , 分隔,然後斷行便於區分。
  • 最後一組鍵值對「不需要」加逗號,否則程式會出錯。
father: 'John',
mother: 'Mary',
daughter1: 'Nancy',
daughter2: 'Juno'

3、我們可以看到光女兒就佔了兩行,好像有點重複,不知道是否可以寫簡單點。
其實有的,下個章節會介紹到的「陣列 Array」就是運用在這,因為陣列特色是可以集合許多事物的相同資訊。

陣列寫法非常簡單,用中括號 [ ] 包覆有相同屬性名的,每個值再用逗號 , 分開,最後一個不需要加逗號。(疑?看起來和定義物件的寫法有點相似!)

像剛剛的女兒1號、2號,其實都是「女兒」的意思(相同屬性名),我們就把屬性名改為女兒們 daughters 便可共用,再把她們的名字通通用陣列放在一起!

daughters: ['Nancy','Juno']

4、和上面第一項的空物件整合之後就變這樣:

const myFamily = {
  father: 'John',
  mother: 'Mary',
  daughters: ['Nancy','Juno'],
};

圖解:

物件型別 object 還有幾個子型別:

  • function (函數)
  • array (陣列)
  • date (日期)
  • regExp (正規表達式)

判斷資料類型 (typeof)

全部的型別都介紹完畢了,我們可以使用 typeof 指令來檢測值的型別是什麼。

console.log(typeof 'Nancy');                  // 回傳 string(字串)
console.log(typeof 593.17);                   // 回傳 number(數字)
console.log(typeof false);                    // 回傳 boolean(布林)
console.log(typeof symbol);                   // 回傳 symbol(符號)
console.log(typeof [1,2,3,4]);                // 回傳 object(物件)
console.log(typeof {name:'Nancy', age:18});   // 回傳 object(物件)
console.log(typeof function(){});             // 回傳 function(函數)
console.log(typeof null);                     // 回傳 object(物件)
console.log(typeof undefined);                // 回傳 undefined(未定義)

不過從上面的程式碼可以看到其中有幾項怪怪的...

console.log(typeof function(){});      // 回傳 function (函數)

我們從 object 物件型別了解到 function 函數是它的子型別,但是根據 MDN 官方文件說明, typeof function(){} 的回傳值會得到 function 而不是 object,雖然如此,它仍屬於物件的一種。

因為函數是一種「可呼叫的物件 Callable Object」,也被稱為「函數物件 Function Object」。函數擁有 [[Call]] 的內部特性,讓它成為能夠被調用的物件。所以如果用 function 當作建構子所建立出來的物件,再用 typeof 檢測值就會回傳是 object 了,就是因為「函數同時也是物件」這樣的特性。

console.log(typeof null);          // 回傳 object (物件)

咦? null 不是應該是基本型別之一嗎,怎麼會是複合型別 object

結果根據 W3C 的說明,它是一個歷史遺留的 Bug!本來在 ES6 中,曾有機會為歷史平凡,將 typeof null 的值翻轉為 null,但最後被拒絕了。原因是歷史遺留程式碼太多了,為了不得罪任何人,不如繼續將錯就錯吧...

有興趣的可以去查一下


參考資料:


上一篇:【JS幼幼班】Step.06 基本語法:基本型別(string、symbol)
下一篇:【JS幼幼班】Step.08 基本語法:物件型別(Array、date)


#javascript #JS幼幼班 #learningJS #JS基本語法







Related Posts

關於這個技術共筆部落格

關於這個技術共筆部落格

[JavaScript] ES6:Destructuring 解構

[JavaScript] ES6:Destructuring 解構

W13_作業二實作記錄

W13_作業二實作記錄


Comments