前面說了幾篇陣列以及陣列方法,今天終於要講到跟陣列息息相關的「物件」了。物件包含著一個以上的屬性與值,可以單一組物件存在,也可以好幾組物件存在於一個陣列之中。
這裡也引用一下 MDN 對物件的說法:
物件是一批相關的數據以及 / 或者功能(通常包含了幾個變數及函式 — 當它們包含在物件中時被稱做「屬性」(properties)或「函式」(methods))
以下示範物件的寫法,可以看到物件裡面可以是字串、數字或是布林值:
// 變數
let farmAnimals = {
// 屬性:值
animal: 'pig',
num: 20,
isEatFood: true
};
console.log(farmAnimals); // {animal: 'pig', num: 20, isEatFood: true}
如果是陣列包著物件,型態會是這個樣子:
let farmAnimals = [
{
animal: 'pig',
num: 20,
isEatFood: true
},
{
animal: 'chick',
num: 50,
isEatFood: true
},
{
animal: 'cow',
num: 10,
isEatFood: false
},
{
animal: 'sheep',
num: 10,
isEatFood: true
},
];
console.log(farmAnimals); // (4) [{…}, {…}, {…}, {…}]
可以看到陣列裡面包著四筆物件。
和陣列一樣,物件屬性也是可以讓人更有效率使用的,讀取的方式很簡單:
// 這邊希望取 animal 屬性的值
let farmAnimals = {
animal: 'pig',
num: 20,
isEatFood: true
};
console.log(farmAnimals.animal); // pig
另外我們更可以針對取出的資料宣告變數,這在一些情況能簡化程式碼,這裡試著示範一個比較長的資料串,方便看出替資料宣告變數的必要性。
let farmAnimals = [
// 1 個物件
{
// 1 個物件
animal1: {
variety: 'pig',
num: 20,
isEatFood: true
},
// 2 個物件
animal2: {
// animal2 第 1 個物件
variety: {
// variet 裡面的 1 個物件
chick: {
chickA: '烏骨雞',
chickB: '力康雞',
chickC: '蘇賽克斯雞'
}
},
// animal2 第 2 個屬性
num: 50,
// animal2 第 3 個屬性
isEatFood: true
},
},
// 2 個物件
{
animal: 'cow',
num: 10,
isEatFood: false
},
// 3 個物件
{
animal: 'sheep',
num: 10,
isEatFood: true
},
];
console.log(farmAnimals[0].animal2.variety.chick.chickC); // 蘇賽克斯雞
以上是一大串複雜的陣列+物件資料,實際上像範例這種陣列包物件又再包物件,或甚至更加複雜的陣列資料是很常見的。
那我來稍微解釋一下上面到底在做什麼好了,這個範例有一個 farmAnimals
陣列,我們需要從這個陣列取出「蘇賽克斯雞」,可以看見 farmAnimals
陣列裡面有三個物件,我們要的「蘇賽克斯雞」在陣列中的第一個物件裡,陣列從 0 開始計算,因此會寫 farmAnimals[0]
,接著又遇到兩個物件,可以看到我們要找的資料在第二個物件,上面有示範物件取值是在前面加上一個「.
」,因此這個資料串又加長了,變成這樣 farmAnimals[0].animal2
,依此類推不斷的向物件裡面取我們要的值,最後就變成這麼一長串。
但試著想像一下,假如我們需要用這串資料來寫 if,是不是 if 括號裡面的程式碼會看起來超級長,如果我們還需要用到邏輯運算子,這括號都到了第二行了XD
於是替這串資料宣告變數就變成必要的了:
let myChick = farmAnimals[0].animal2.variety.chick.chickC
console.log(myChick); // 蘇賽克斯雞
現在可以看到這一串資料瞬間變的很清爽。
在陣列的時候有提到,我們可以在必要的時候新增一個空陣列,同樣的物件也可以。
let farm = {};
farm.animal = 'pigeon';
farm.num = 10;
console.log(farm); // {animal: 'pigeon', num: 10}
farm.animal
代表的是,我選取了 farm
這個空物件,並且我增加了一個 animal
屬性,賦予了一個值 pigeon
。
修改的作法其實跟新增的步驟一樣。
let farm = {};
farm.num = 20;
console.log(farm); // {animal: 'pigeon', num: 20}
在字串上我們可以直接像上面這樣子的寫法,不過也有另一種寫;假設鴿子的數量我想要再增加一隻,於是可以這麼寫 farm.num += 1
。
物件在刪除的部分也是很直接的使用 delete
,就像範例中的物件資料,蔬菜已被刪除^w^
let food = {
foodA: 'vegetable',
foodB: 'fruit',
foodC: 'fish',
foodD: 'beef',
}
delete food.foodA;
console.log(food);
// {foodB: 'fruit', foodC: 'fish', foodD: 'beef'}
let food = {
foodA: 'vegetable',
foodB: 'fruit',
foodC: 'fish',
foodD: 'beef',
}
let delicacy = 'foodD';
console.log(food[delicacy]); // beef
有的時候也會需要使用到這樣的讀取方式,稍微解釋一下他的步驟,會先將 delicacy
變數的字串取出即是 food[foodD]
,然後再從 food[foodD]
取出值 'beef'
。
那麼究竟什麼時候我們可能會用到上面討論的方法呢?在更上面的地方我有提到,其實在抓取陣列物件資料的時候,是很容易遇到組合很複雜甚至匪夷所思的情況,譬如說:
let food = {
foodA: 'vegetable',
foodB: 'fruit',
'089': 'beef',
}
console.log(food['089']); // beef
可以看到 '089'
這個字串是沒有辦法用上述普遍使用的方法去抓取值的,因此會需要使用例外的方法處理。
這篇沒有寫到太多的理論,主要是我自己在學習的時候其實也沒有特別去查物件是什麼,只是看了範例了解他的概念以後,就開始不斷的練習,寫這篇文章的時候也是以多練習也可以活用的角度,因此如果需要看物件的理論,還是建議可以看一下 MDN。