---
# System prepended metadata

title: Javascript第六章 物件與陣列
tags: [JS X Codeshiba]

---

# Javascript第六章 物件與陣列
###### tags: `JS X Codeshiba`

## 何謂物件
所有基本型別(Primitives)以外的值都是物件
定義: An object is a collection of properties and has a single prototype object.
**物件** 可以是 **零至多種屬性的集合** 
**屬性** 鍵(Key)與值(Value)之間的關聯，值可以是另一個物件，甚至可以是一個函數

不可變的基本型態只能代表一個值，物件可以代表多個或複合值，而且可以在它的生命週期中改變

```javascript=
const obj = {};

```



## 如何宣告物件
物件的內容叫做屬性(Property)或成員(Member)
1. 用大括號宣告
2. 一個(鍵)Key對應一個值(Value)
3. 值又稱為屬性(attribute)




![](https://i.imgur.com/h22QVMw.png)
![](https://i.imgur.com/XmVf2ve.png)
第一種
```Example1
var person = new object();

person.name = "Kuro";
person.job = 'Front-end developer';
person.sayName = function(){
    alert(this.name);
};
```
第二種 較為常見~
物件實字(Object literal)，也是JSON格式的核心語法
```Example2
    var person = {
      name: 'Kuro',
      job: 'Front-end developer',
      sayName: function() {
        alert(this.name);
      }
    }
    console.log(person);
```
![](https://i.imgur.com/wgxRK5E.png)

**請注意**
宣告物件時，內部的key和value的寫法為
key : value 中間用 , 來分隔
而不是 key = value 然後中間用 ; 來分隔 


## 如何存取物件的屬性?
屬性名稱必須是有效的識別碼，如果特性名稱不是有效的識別碼，就必須使用計算成員存取(computed member access)運算子

方法一: 可以透過.的方式
```Example
    var person = {
      name: 'Kuro',
      job: 'Front-end developer',
      sayName: function() {
        alert(this.name);
      }
    }
    console.log(person);
    person.name="Steven";
    person.job="No job";
    console.log(person);
```
![](https://i.imgur.com/jeVY0G7.png)

方法二: 可以透過[""]或是['']的方式
```
    var person = {
      name: 'Kuro',
      job: 'Front-end developer',
      sayName: function() {
        alert(this.name);
      }
    }
    console.log(person);
    person["name"]='Lukas';
    person["job"]='Instructor';
    console.log(person);
```
![](https://i.imgur.com/FsAPtJb.png)

用方法一時，如果有不允許的命名方式，則會被糾錯出來
![](https://i.imgur.com/V1vfdhE.png)




## 如何抓取變數內的資料
![](https://i.imgur.com/MOKc3B3.png)

如果是function，則需要加上()才可以運作喔
![](https://i.imgur.com/3VKOHBB.png)

## 如何增加屬性
可以透過'.屬性名稱'即可增加屬性
```
obj.age='13';
```
![](https://i.imgur.com/f0v72sR.png)


## 如何刪除屬性
可以透過delete來刪除屬性
```
delete obj.age;
```
![](https://i.imgur.com/gyIxSFw.png)

## 物件內還有物件?
```javascript=
const sam1 = {
    name: 'Sam',
    age: 4,
};

const sam2 = {
    name: 'Sam',
    age: 4
};

//特性值可以是物件
const sam3 = {
    name: 'Sam',
    classification: {
        kingdom: 'Anamalia',
        phylum: 'Chordata',
        class: 'Mamalia',
        order: 'Carnivoria',
        family: 'Felidae',
        subfamily: 'Felinae',
        genus: 'Felis',
        species: 'catus',
    },
};
```

```javascript=
// 如何呼叫物件內的物件屬性?
sam3.classification.family;
sam3["classification"].family;
sam3.classification["family"];
sam3["classification"]["family"];
```

## 把函式加入物件
```javascript=
sam3.speak = function(){
        return "Meow!";
};

sam3.speak(); //即可呼叫函式
```
## 判斷屬性是否存在
只要是不存在的屬性，都會回傳undefined，若是想要判斷屬性是否存在，但如果剛好屬性是undefined時，就沒用了...

此時可以使用hasOwnProperty來確認屬性的狀態
```
obj.hasOwnPeroperty('name')
```
![](https://i.imgur.com/UTUZNQ2.png)




```
  <script type=text/javascript>
  //建立空白物件
  var point=new object();
```
```  
  //建立物件的成員(屬性與方法)
  point.x=3;//屬性
  point.y=4;
  point.getPosition=function(){//方法
    alert(this.x+","+this.y);
  };
```
```  
  //使用物件
  point.getPosition();
```

綜合範例:遊戲中的玩家設計
```
  //物件的設計
  var player=now object();
  player.name="john";
  player.hp=100;
  player.fight=function(){
    this.hp=this.hp-2;
  };
  player.rest=function(){
    this.hp++;
  };
  player.report=function(){
    alert(this.name+":"+this.hp);
  };
```
```
  //物件的使用
  player.fight();
  player.rest();
  player.report();
  
  </script>
```
按照上述的做法，每建立一隻角色就要重新寫一次
使用this代表新建的空白物件
可以使用該手法來方便創建新的角色
```
  <script type=text/javascript>
  function PlayerModel(name,hp,atk) {
    this.name=name;
    this.hp=hp;
    this.atk=atk;
    this.fight=function() {
      this.hp-=2;
    };
    this.rest=function() {
      this.hp++;
    };
    this.report=function() {
      alert(this.name+" hp: "+this.hp+" atk: "+this.atk);
    };
  }
  var player = new PlayerModel("Steven", 100, 20);
  player.fight();
  player.fight();
  player.fight();
  player.fight();
  player.fight();
  player.fight();
  player.report();
  </script>
```

## 數字、字串與布林物件
數字、字串與布林都有對應的物件型態(Number、String與Boolean)
這些物件有兩種目的:
1. 儲存特殊的值(e.g. Number.INFINITY)
2. 以函式的形式來提供功能

```javascript=
const s = "hello";
s.toUpperCase(); //"HELLO"
```

看起來好像s變成了一個物件，但是這只是暫時性的，並不是s真的成為一個物件

```javascript=
const s = "hello"; 
s.rating = 3;
s.rating; //undefined
```

## 陣列介紹
陣列，是種「特別」的物件，沒有規定只能放甚麼東西進去，同一個陣列可以是原始的資料類型、另一個陣列、物件甚至是函式等等。

與物件不同的是，陣列是有順序性的集合，且鍵(key)是數字，所以只能透過[]加上索引來存取


![](https://i.imgur.com/y65dXOq.png)
![](https://i.imgur.com/5fD6746.png)
![](https://i.imgur.com/ffLdzuZ.png)

## 刪除陣列最後一個元素(pop)
![](https://i.imgur.com/RijrnFi.png)

## 陣列特性
1. 陣列大小是不固定的，可以隨時新增或移除元素
2. 陣列內容不一定是同一種型態，每一個元素都可以使用任何型態
3. 陣列是從0開始的，也就是說，陣列的第一個元素是元素0

## 新增陣列元素
可以透過new array的方式來新增
並透過length或console.log的方式來驗證
```Example
var a = new Array();
    a[0] = "apple";
    a[1] = "boy";
    a[2] = "cat";

    a.length;  
    console.log(a.length);
    console.log(a);
```
![](https://i.imgur.com/D8QuKL2.png)

亦可以透過陣列實字(Array Literal)的方式來進行
```Example
var a = [];
    a[0] = "apple";
    a[1] = "boy";
    a[2] = "cat";

    console.log(a.length);
    console.log(a);
```
![](https://i.imgur.com/aunX726.png)

或是直接賦值的方式亦可
```Example
var a = ["apple","boy","cat"];

    console.log(a.length);
    console.log(a);
```
![](https://i.imgur.com/jVFiS6f.png)

陣列的內容也可以透過length來覆寫，操作後的內容則無法回復
```Example
    var a = ['apple','boy','cat'];
    a.length=1;
    console.log(a);
    a.length=3;
    console.log(a);
```

![](https://i.imgur.com/Iho1XJ3.png)




## 透過索引新增、修改與提取陣列元素
有趣的是，可以透過索引直接新增，但不用依循連續的原則來指定，中間未指定的變數會用undefined呈現
```Example
var a = ['apple','boy','cat'];
    console.log(a.length);
    a[7] = 'z';
    console.log(a);
```

![](https://i.imgur.com/uPj4bs3.png)

![](https://i.imgur.com/Qgh2cOy.png)

或是用push來新增元素
```Example
    a.push('yoyo','girl','nana')
    console.log(a);
```
![](https://i.imgur.com/Ny07eNq.png)


## 獲取陣列索引值
![](https://i.imgur.com/SVFITYu.png)

## 切片的手法
![](https://i.imgur.com/78eljQk.png)

## 陣列的進階手法 map()
可以透過map來修改陣列的呈現內容

![](https://i.imgur.com/0ttNCVQ.png)

![](https://i.imgur.com/bapBJRJ.png)

## 如何透過for迴圈來修改陣列?
![](https://i.imgur.com/NzkevHo.png)

那如何回傳for迴圈的修改結果呢?
![](https://i.imgur.com/sgsB8RL.png)

![](https://i.imgur.com/cq9s5Tt.png)


## 如何把陣列內所有內容讀過一遍? forEach()

forEach()的基本用法
![](https://i.imgur.com/akCXtK4.png)

無法直接把結果賦值給變數形成陣列，跟map不一樣
![](https://i.imgur.com/RhahL2m.png)

用for迴圈重現結果
![](https://i.imgur.com/ajHiC40.png)

## 如何列出陣列中符合條件的元素? filter()
filter()的基本用法
![](https://i.imgur.com/pbvYRLd.png)

包含不同資料類別的陣列型態如何搜尋?
![](https://i.imgur.com/QfHrlbu.png)

## 查找資料中的第一筆資料(VLOOKUP) find()
類似filter()的功能，但其實有些差異
![](https://i.imgur.com/nIe2tpF.png)

## 甚麼是Array.prototype?
Array.prototype

[MDN的資料](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype)


```
表示 Array 構造函数的原型，允許向所有Array對象添加新的属性和方法。
```

## 用reduce()來計算陣列元素的加總結果
![](https://i.imgur.com/BZrQk3I.png)

可以透過瀏覽器內建的監控視窗來增加變數來看相關的變化
重新整理後就可以持續看相關的變化
![](https://i.imgur.com/XBsaAJh.png)

## 物件與陣列的最後一個逗號
```javascript=
    const arr = [
    "One",
    "Two",
    "Three",
    ];
    const 0bj = {
    one : 1,
    two : 2,
    three : 3,
    }
```

使用最後的逗號代表永遠不需要在前一行程式碼加上逗號，但這並非必須
例如JavaScript物件標記法(JavaScript Object Notation，JSON)是一種常用的JavaScript式資料與法，它不容許最後的逗號。

## 日期
JavaScript的日期和時間是用內建的Date物件來表示的。
```javascript=
const now = new Date();
now; 
//main.js:33 Sat Apr 03 2021 23:36:40 GMT+0800 (GMT+08:00)
```

建立一個具有特定日期的初始值
```javascript=
//注意月份是從0開始的，所以10月等於9月
const halloweenParty = new Date(2021, 9, 31);
//Sun Oct 31 2021 00:00:00 GMT+0800 (GMT+08:00)
```

建立一個具有特定日期與時間的初始值
```javascript=
const halloweenParty = new Date(2021, 9, 31, 19, 0);
console.log(halloweenParty);
//Sun Oct 31 2021 19:00:00 GMT+0800 (GMT+08:00)
```

也可以取出內部的元件
```javascript=
console.log(halloweenParty.getFullYear()); //  2021
console.log(halloweenParty.getMonth()); // 9
console.log(halloweenParty.getDay()); // 0
console.log(halloweenParty.getDate()); // 31
console.log(halloweenParty.getHours()); // 19
console.log(halloweenParty.getMinutes()); // 0
console.log(halloweenParty.getSeconds()); // 0
console.log(halloweenParty.getMilliseconds()); // 0
```

## 正規表達式
正規表達式(regular expression)，簡稱regex或regexp，為JS的一種子語言，是許多程式語言會提供的擴充語言

[參考資料-email識別器](https://dezchuang.github.io/2017/07/05/022_regexp_1/)

## 資料型態轉換

### 轉換成數字
1. 使用Number物件建構式
在使用建構式時，不會不使用new關鍵字，所以這算是特殊案例

```javascript=
const numStr = "33.3";
const num = Number(numStr); //這會建立一個數字值
```
2. 使用內建的parseInt和parseFloat函式
使用parseInt時，可以指定一個radix，這是被解析的數字基數

```javascript=
const a = parseInt("16 volts" , 16);
//忽略文字，直接以基數來解析
const b = parseInt("3a", 10);
//以16進位解析，結果為58
const c = parseFloat("15.5 kph");
//一定會假設基數為10
```

Date物件可以用valueOf()來轉換成一組數字，代表從1970年1月1日午夜算起的毫秒數
```javascript=
const d2 = d.valueOf();
console.log(d2);
//1617466405820
```
### 轉換成字串
JS裡面所有物件都有toString的方法，它會回傳字串表示形式。使用toString()的方法，可以把數字轉換成文字

```javascript=
const e = 33.5;
const f = [1, true, "yoyo"];

e1 = e.toString();
f1 = f.toString();

console.log(e1); //33.5
console.log(f1); //1,true,yoyo
```

### 轉換成布林


```javascript=
const n = 0;
const b1 = !!n; //使用兩個Not運算子(!)來把任何值轉成Boolean
const b2 = !n; //使用一個Not運算子(!)也可以轉成Boolean，但結果會相反
const b3 = Boolean(n); //使用布林建構式(結果: false)


console.log(b1);
console.log(b2);
console.log(b3);
```

## 結論
1. JS內的所有數字都是雙精確度浮點數
2. 我們常用的其他資料型態(日期、map、set、正規表達式)都是特殊的物件型態
3. 掌握字串樣板與轉義，會是本章的學習重點