---
# System prepended metadata

title: js 物件
tags: [javaScript]

---

# js 物件

https://medium.com/enjoy-life-enjoy-coding/javascript-%E9%97%9C%E6%96%BC-object-%E4%B8%80%E5%8F%A3%E6%B0%A3%E5%85%A8%E8%AA%AA%E5%AE%8C-4bb924bcc79f

## 使用
使用 Object 中的 Property 方式有兩種：

**. 點號運算子**，只要在 Object 名稱後使用 . 並指定 Property 的 key ，即可讀取該特性的值。

**[] 中括號**，在中括號裡可以是一個述句，會經由運算，並將值轉為字串後尋找對應的 key 值。

```
//使用 . 點號運算子
console.log(mary.name)  
//印出 Mary

//使用 [] 中刮號運算子
const propertyNameA = 'say'
const propertyNameB = 'Hello'
mary[propertyNameA + propertyNameB]()  
//取出 function 後執行，印出 Hello Mary
```

## crud
```
//異動 Property 的值
mary.name = `${mary.name} Louise`

//新增一個 Property 
mary.friends = ['Jane','Leda']
```

```
//賦予一個新的 Property 
mary.age = 18

//刪除該 Property 
delete mary.age
//成功時回傳 true

//該特性消失，在使用時回傳 undefuned
console.log(mary.age)
//undefined
請注意！這與直接指定該 Property 的值為 undefined 不同， delete 會讓 Property 從 Object 中消失
```
## this

forEach 內執行的 Function 並不是建立在 mary 中，因此他之中的 this 就不會指向 Object 本身，而是代表全域的 Window 

Function 時使用 call 、 apply 、 bind 指定 this ，以下先簡單介紹這三個的差別及用法

**call** 時，只需將要指定的 this 放入第一個參數，其餘從第二個開始傳入 Function 中

```
const mary = {
    name: 'Mary',
}

function writeSpeak(talk){
    console.log(`${this.name} say ${talk}`)
}

//使用 call 對 writeSpeak 指定 this
writeSpeak.call(mary,'Hello')
//印出 Mary say Hello
```
**apply**的使用方式和 call 相同，只是在傳入要執行的 Function 需要的參數時，需將所有的參數放置於一個陣列中

```
const mary = {
    name: 'Mary',
}

function writeSpeak(talk){
    console.log(`${this.name} say ${talk}`)
}

//使用 apply 需要將傳入的參數都放進一個陣列中
writeSpeak.apply(mary,['Hello'])
```

**bind** 與 call 傳入參數的方式相同，但 bind 並不會馬上執行 Function ，而是會回傳一個新的 Function 
```
const mary = {
    name: 'Mary',
}

function writeSpeak(talk){
    console.log(`${this.name} say ${talk}`)
}

//bind 會回傳一個新的 Function
const marySayHello = writeSpeak.bind(mary,'Hello')

//需另外執行
marySayHello()
//印出 Mary say Hello

//也可以不在一開始就給參數
const marySay = writeSpeak.bind(mary)

//執行時再給參數
marySay('Good bye')
//印出 Mary say Good bye
```

## Property attributes 特性屬性

Property 是由一個 key 及 value 定義的，但是嚴格來說， value 只是這個 Property key 的一個屬性而已，除了 value 外還有其他三個沒再露面的 Property attributes 


* writable ：代表此 Property 可否重新指定值，預設為 false。
* enumerable ：代表此 Property 的可列舉性，受到影響的會有 Object.keys() 及 for(key in obj) 等，預設為 false。
* configurable ： 代表此 Property 的可控制性，能夠讓物件的 Property 無法被刪除，預設為 false

## Constructor 建構器
Constructor （建構器）是一個 Function ，可以利用它來建立一些相似的 Object ，被 Constructor 建立出來的 Object 被稱為它的 Instance （實體）， Constructor 在使用時與一般 Function 不同，是藉由 new 來呼叫，也就是說，它只有再藉由 new 的狀態下使用才會是 Constructor 。

```
// Constructor 第一個字母通常大寫
function Person(name){
    //設定 this 的 name property 值為傳進來的參數， this 為建立的物件
    this.name = name
}
//用 new 呼叫 Person 使它成為一個 Constructor ，替 mary 及 kitty 設定 name
const mary = new Person('Mary')
const kitty = new Person('Kitty')

mary.name 
// Mary

//每個 Instance 的 constructor 屬性都會指向 Constructor 本身
kitty.constructor === Person
// true
```
在上方的例子中，就可以說 mary 和 kitty 是 Person 的 Instance ，也可以發現 Constructor 能協助建立擁有基本資料的 Object ，而要處理這些 Object 的 Function 便能放在 Prototype 中，以達成資料在 Constructor 的 Instance ， 方法在 Prototype 的關注點分離原則。

但是藉由 Constructor 建立的 Object 就不會再經過 Object.create ，該如何對那些 Instance 設定 Prototype 呢？答案在 Constructor 中，每一個 Constructor 都擁有 Prototype 的屬性，可以把方法設定在 Prototype 中，如此一來，只要是透過該 Constructor 建立的 Instance ，也都會擁有相同的 Prototype ：

```
// Constructor
function Person(name){
    this.name = name
}

//設定 Prototype
Person.prototype.sayHello = function(){
    console.log(`Hello ${this.name}`)
}

const mary = new Person('Mary')
const kitty = new Person('Kitty')

mary.sayHello()
//印出 Hello Mary

// Prototype 會指向 constructor 的 prototype
Object.getPrototypeOf(kitty) === Person.prototype
// true
```


## ES6 物件裡面 key value簡化
```
const a = 'a'

const b= {
    a
}
```

等於

```
const a = 'a'
const b= {
    a:a
}
```

物件的話也可以
```

const a ={
    c:'c'
}

const b = {
    a
}
```

也能傳進來


###### tags: `javaScript`