# 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. 掌握字串樣板與轉義,會是本章的學習重點