---
# System prepended metadata

title: JS 核心 10 - 物件結構
tags: [JS 核心, ' Javascript', ' 物件結構']

---

---
title: 'JS 核心 10 - 物件結構'
tags: JS 核心, Javascript, 物件結構
description: 2021/02/05
---

JS 核心 -- 物件
===

## 如何定義物件
### 物件實字 Object Literals (宣告式) : 直接定義物件，並插入值。
1. 一個屬性對應一個值 
2. 屬性間用「，逗號」隔開  (最後一個屬性可以不用加逗號)
3. 值可以是純值、物件、函式
4. 可在物件建立時一次全部加入

```
var family = {
  屬性    :  值,
  property: value,
}   // 使用物件實字的方式宣告的物件結構
```
```typescript
var family = {
    name: '小明家',  // 字串
    deposit: 1000,  // 數字純值
    members: {      // 物件結構
      mom: '老媽',
      ming: '小明'
    },
    callFamily: function() {   // 插入函式
      console.log('聯絡小明家');
    }
 }; 
console.log(family);
```
![](https://i.imgur.com/k0E8P4G.png)


### 物件建構式 : 使用建構式宣告物件
建構形式必須在物件建立後一筆一筆新增

```typescript=13
var newFamily = new Object(family);
console.log(newFamily);  
```
```
var newFamily = new Object(1);    // 若插入數值
console.log(newFamily);           // Number {1}，出現 number 的包裹物件
```
```
var newFamily = new Object('1');  // 若插入字串
console.log(newFamily);           // String {"1"}，出現 string 的包裹物件
```

## 物件取值、新增、刪除
### 物件取值
* **使用「點 ․」取值 : 物件的變數名稱․屬性** ;「點 ․」後面只能接字串
* **使用 「 中括號 [ ] 」 取值 : 物件的變數 ['屬性']** 
    * <span class="red">若用 [  ] 來取值，除了數字外，裡面需用引號包住需要取值的屬性名稱</span> 
    * <span class="red">若屬性名稱為數字則可以不用引號包住，直接取值即可</span> 
    * 也可使用變數的方式來取值  
    
<span class="red">✏ 物件取值方式一律使用**字串**的方式取值。  
✏ 所有的物件屬性都是字串。 </span> 

```typescript=
var family = {
  name: '小明家', // 字串
  deposit: 1000,  // 數字純值
  members: {      // 物件結構
    mom: '老媽',
    ming: '小明'
  },
  1 : '1',
  '$-小明家' : '$-小明家 string' , // 物件裡的"屬性"定義上一律是字串，可以使用特殊字元
  callFamily: function() {
     console.log('聯絡小明家');
  }
}; 
console.log(family.members);      // {mom: "老媽", ming: "小明"}
console.log(family.members.mom);  // 老媽
console.log(family.name);         // 小明家 (使用「 點 ․ 」取值)
console.log(family['name']);      // 小明家 (使用「中括號[ ]」取值)

var a = 'name';           
console.log(family[a]);   // 小明家  (使用變數的方式取值)

console.log(family.1);    // 跳錯 (物件取值方式一律使用字串的方式取值)
console.log(family[1]);   // 1 若屬性名稱為數字可以不用引號包住
console.log(family['1']); // 1 
console.log(family['$-小明家']);   // $-小明家 string

family.callFamily();      // 聯絡小明家 (取物件裡的函式來執行)
family['callFamily']();   // 聯絡小明家 (取物件裡的函式來執行)
```

### 物件新增
```typescript=
var family = {
  name: '小明家', // 字串
}; 
family.dog = '小白';       // (使用「點 ․」新增屬性)
family['kitten'] = '小貓'; // (使用「中括號[ ]」新增屬性)
family['$'] = 'money';
console.log(family);  // {name: "小明家", dog: "小白", kitten: "小貓", $: "money"}
```

### 物件刪除
```typescript=8
delete family.dog;
delete family['$'];
console.log(family);  // {name: "小明家", kitten: "小貓"}
```

## 變數及物件屬性的差異
### 變數無法被刪除，屬性可以被刪除
window 是瀏覽器的根物件，打開後裡面有許多屬性
```
var a = 1;  // a 為變數
b = 2;      // b 是透過屬性的方式新增，等同 window.b = 2
console.log(window);  // (如下圖) 發現 a 和 b 同時賦予到 window 這個根物件上

delete a;  // a 是使用變數的方式新增，不能被刪除
delete b;  // b 是使用屬性的方式新增，可以被刪除
console.log(window);   // a 還在， b 不見了

console.log(a);  // 1 (a 還在)
console.log(b);  // b is not defined (b 不見了)
```
![](https://i.imgur.com/oqQbbVm.png)

至「開發人員工具」查看  
發現 a 為變數，無法被刪除 ; b 為屬性，可以被刪除  
![](https://i.imgur.com/vcXBlHw.png)


## 物件與純值
> **JavaScript 只有兩種型別 : 純值、物件。**  
> 純值指的是原始型別。

> 當判斷一個值無法新增屬性時，就是純值。

### 物件可以透過「點 ․」來新增屬性
透過**物件十字**的方式宣告一個物件，透過「點 ․」來新增物件屬性

```
var family = {}; 
family.name = '小明家';  // 物件裡新增 name 屬性
console.log(family);    // {name: "小明家"}
```

### 純值無法新增屬性

#### <span class="red">純值</span> 無法新增屬性
```
var newString = '小明家';  // 新增字串
newString.name = '小明';   // 在此字串下新增屬性
console.log(newString);   // 小明家 (純值無法新增屬性)
```

#### 使用建構式的方式來新增字串
```
// 以建構式建立的字串並非純值
var newString2 = new String('小明家');
console.log(newString2);  // String {"小明家"}，本身是一個字串，包含"小明家"的內容
newString2.name = '小明';
console.log(newString2);  // String {"小明家", name: "小明"}
```

#### 使用陣列的方式來新增屬性
```
var newArray = [1, 2, 3]; 
console.log(typeof newArray);  // object (陣列也屬於物件型別)

newArray.name = '小明';  // 可以自由新增屬性
console.log(newArray);  // [1, 2, 3, name: "小明"]
```

#### function 是物件型別下的子型別
```typescript=
function callName(){
  console.log('呼叫小明'); 
}
console.log(typeof callName);   // function (函式是物件型別下的子型別)
console.log(callName);   
/* 看到函式的本身
  ƒ callName(){
    console.log('呼叫小明'); 
  }
*/
```
### 使用 console.dir(object); 印出該對象的所有屬性和屬性值。  
函式變成物件的型式，多了被呼叫的能力，展開觀察~ (參考左圖)
```typescript=11
console.dir(callName);  // ƒ callName()，看到物件的所有屬性內容
```
![](https://i.imgur.com/kBZ02PJ.png)


試著再加入 name 的屬性    (參考左圖)
> <span class="red">屬性 name 是函式本身的名稱，無法被修改。</span>
```typescript=12
callName.name = '小明';   // 新增 name 的屬性
console.dir(callName);   // 函式裡面的 name 屬性無法被覆蓋
```

再試著插入其他屬性  (參考右圖)
```typescript=14
callName.ming = '小明';   // 新增 ming 的屬性
console.dir(callName);   // 函式裡面新增了 ming 的屬性
```




## :memo: 學習回顧
:::info
* 物件實字 Object Literals (宣告式) : 直接定義物件，並插入值
    * 可在物件建立時一次全部加入
 * 物件建構式 : 使用建構式宣告物件
    * 建構形式必須在物件建立後一筆一筆新增
* 物件取值
    * 使用「點 ․」取值 :「點 ․」後面只能接字串，不能接數字
    * 使用 「 中括號 [ ] 」 取值 : 物件的變數 [‘屬性’] (需用引號包住)
* 使用 「 中括號 [ ] 」 取值
    * 若用 [ ] 來取值，除了數字外，裡面需用引號包住需要取值的屬性名稱
    * 若屬性名稱為數字則可以不用引號包住，直接取值即可
    * 也可使用變數的方式來取值  
✏ 物件取值方式一律使用字串的方式取值  
✏ 所有的物件屬性都是字串  
* 變數無法被刪除，屬性可以被刪除
* JavaScript 只有兩種型別 : 純值、物件。
    * 純值無法新增屬性
* 使用 console.dir(object); 印出該對象的所有屬性和屬性值。
函式會變成物件的型式。
    * 屬性 name 是函式本身的名稱，無法被修改。
:::

## :+1: 相關參考文件 
:::info
[你懂 JavaScript 嗎？#17 物件（Object）](https://cythilya.github.io/2018/10/24/object/)  
[Javascript 是個真正的「物件」導向程式語言](https://medium.com/schaoss-blog/javascript-%E6%98%AF%E5%80%8B%E7%9C%9F%E6%AD%A3%E7%9A%84-%E7%89%A9%E4%BB%B6-%E5%B0%8E%E5%90%91%E7%A8%8B%E5%BC%8F%E8%AA%9E%E8%A8%80-bfefa55f272f)
:::


<style>
.red {
  color: red;
}
.green {
  color: green;
}
</style>