---
title: 'JS 核心 11 - 未定義的物件屬性、物件的參考特性'
tags: JS 核心 ,JS , JavaScript, 未定義的物件屬性, 物件的參考特性
description: 2021/02/09
---
JS 核心 -- 未定義的物件屬性 與 物件的參考特性
===
## 未定義的物件屬性
### 物件下未定義屬性,值為 undefined,在 undefined 上也無法再新增屬性
透過物件十字的方式建立物件
```typescript=
var family = {
name: '小明家',
}
console.log(family); // {name: "小明家"}
```
> 若在物件下查找一個不存在的屬性,會回傳 undefined 的結果
試著在 family 物件下查找一個不存在的屬性 ming
```typescript=5
console.log(family.ming); // undefined,無此值
```
> 無法新增任何屬性在 undefined 上
```typescript=6
family.ming.name = '小明'; // 跳錯,無法對 undefined 的值新增 name 屬性
// Cannot set property 'name' of undefined (family.ming 不存在)
```
### :pencil: **解決方法 :**
1. **在建立物件十字時**,同時建立 ming 的屬性,就可把 name 屬性加上去。
除了有 name 的屬性外,在 ming 裡面有正確加上 name 的屬性。
```
var family = {
name: '小明家',
ming: {}
}
family.ming.name = '小明';
console.log(family);
```

2. 若在一開始無法確定結構的情況下 : 直接**在物件下**新增屬性 (結果同上)
```
var family = {
name: '小明家',
}
family.ming = {
name: '小明',
};
console.log(family);
```
### 對全域物件下的屬性作檢查,要使用 window.a 查找
錯誤示範
```
var family = {
name: '小明家',
}
console.log(a); // a is not defined,跳錯,程式碼中斷,後面不會執行
console.log(family);
```
正確示範 : 未定義的物件屬性會回傳 undefined
```
var family = {
name: '小明家',
}
console.log(window.a); // undefined , 後面程式碼可以執行
console.log(family); // {name: "小明家"}
```
---
## 物件的參考特性
### JavaScript 賦予值在變數上時,有兩個特性 : 傳值、傳參考

### 變數為純值 : 透過傳值的方式做傳遞,<span class="red">沒有</span>傳參考的特性
* <span class="green">傳值是一種複製的概念</span>
* 直接把 person 原本的值帶給 person2,person2 接收 ’小明’ 這個值
* <span class="green">傳值過去後,就和前者的值無關聯性</span>
* person2 值怎麼修改就和前面無關聯性
* 把 person2 改為 ’杰倫’,原本的 person 還是維持 ’小明’ 的狀態
```
var person = '小明'; // 先宣告一個純值的變數
var person2 = person; // 宣告另一個變數,把'小明'的值賦予在此變數上
person2 = '杰倫';
console.log(person, person2); // 小明 杰倫
```

### 變數為物件 : 物件<span class="red">有</span>傳參考的特性
#### 改變物件內容時,前一個也會受到更動,即為物件傳參考特性
> 使用同一個參考路徑,只對應一個物件
```
var person = {
name: '小明',
money: 1000
}
var person2 = person;
```
1. 定義 person 等於一個物件的時候,執行結果如下圖
2. 定義 person,後面帶入的是記憶體的參考路徑 (並不是帶入完整的物件內容)
3. 當參考路徑指向物件時,可取得裡面的 name、money 內容
4. person 不會把 name、money 的值存到記憶體空間,只會傳入一個參考

把 person2.name 改為'杰倫';
```
person2.name = '杰倫';
console.log(person, person2); // {name: "杰倫"} {name: "杰倫"}
console.log(person === person2); // true
```
5. 把 person2 裡的 name 改為 ’杰倫’,因為都使用同一個參考物件
( person 和 person2 裡的 name 同時受到修改)
6. 只有產生一個參考路徑,一個參考路徑對應一個物件 ( person 和 person2 共用同一個物件)

:pencil2: **範例 : 傳參考 (若指向另一個物件,就會產生另一個參考位置)**
> 當宣告一個物件時,就等於在記憶體空間上準備了新的參考位置
> 不同的參考位置就算屬性和值相同,但兩者比對還是 false
1. 一開始定義 person 物件,person 物件指向 0x01 這個參考位置
2. 又定義 person2 物件指向前一個 person 物件,兩者共用 0x01 這個參考位置 (如左圖)
```
var person = {
name: '小明',
money: 1000
}
var person2 = person;
```
試著將 person2 指向新物件
```
person2 = { // 指向新的物件,就會產生新的參考位置
name: '小明',
}
console.log(person, person2); // {name: "小明"} {name: "小明"}
console.log(person === person2); // false,person 和 person2 無關聯性
```
3. 當指向另一個物件時,就會產生新的參考位置 (如右圖)
4. person 和 person2 無關聯性。 就算 person2 修改 name 內容,person 也不會改變。

## :memo: 學習回顧
:::info
* 物件下的未定義屬性,值為 undefined,在 undefined 上也無法再新增屬性
* 對全域物件下的屬性作檢查,要使用 window.a 查找
* JavaScript 賦予值在變數上時,有兩個特性 : 傳值、傳參考
* 純值透過<span class="red">傳值</span>的方式做傳遞 (沒有傳參考的特性)
* 物件有<span class="red">傳參考</span>的特性
* 當宣告一個物件時,就等於在記憶體空間上準備了新的參考位置
* 不同的參考位置就算屬性和值相同,但兩者比對還是 false
:::
## :+1: 相關參考文件
:::info
[JavaScript 物件的連連看!? 兩個物件的值居然會一樣](https://wcc723.github.io/javascript/2017/12/10/javascript-reference/)
:::
<style>
.red {
color: red;
}
.green {
color: green;
}
</style>