--- title: 'JS 核心 14 - 陣列、JSON、課後練習' tags: JS 核心 ,JS , JavaScript, 陣列, Array, JSON description: 2021/02/10 --- JS 核心 -- 陣列、JSON、課後練習 === ## 陣列 > JavaScript 只有**原始型別**及**物件型別**兩種 > 陣列也是物件型別的一種 ### 使用陣列十字的方式定義陣列,直接插入**值**就可以了 :pencil2: **取陣列的值 : array [索引位置]** :pencil2: **於陣列中插入新值 : array.push (值)** ``` var newArray = [ 1, // 原始型別: 數字 '文字', // 原始型別: 字串 true, // 原始型別: 布林值 { name: '小明' // 物件型別 } ]; console.log(newArray); // (4) [1, "文字", true, {…}],有 4 筆資料 (如下圖) console.log(newArray[3]); // {name: "小明"} newArray.push(5); // 於陣列後方插入新值 5 console.log(newArray); // (5) [1, "文字", true, {…}, 5],有 5 筆資料 ``` ![](https://i.imgur.com/dDb409j.png) :pencil2: **物件可以新增屬性 ; <span class="red">陣列增加屬性內容,不會影響陣列長度** </span> > 新增屬性至陣列中,並不是增加一個資料進去陣列,故不會列入陣列長度。 若對陣列新增屬性 : 陣列長度不變,但新增屬性 name 則不屬於陣列裡的長度 ```typescript= var newArray = [ 1, '文字', true, { name: '小明' } ]; newArray.push(5); newArray.name = '小明'; console.log(newArray); // (5)[1, "文字", true, {…}, 5, name: "小明"] ``` :pencil2: **也可使用中括號 [ ] 新增值 : 若中間有空的部分,會自動補上空值 ( 顯示 undefined ),也會影響陣列的長度** 跳過 "索引位置 6" , 從 "索引位置 7" 插入新值 "索引位置 6" 為空值,顯示 undefined :pencil2: **使用 array.length 的方法把陣列長度印出** ```typescript=12 newArray[5] = '杰倫'; // 索引位置 5 為 '杰倫' newArray[7] = '漂亮阿姨'; // 索引位置 7 為 '漂亮阿姨' console.log(newArray); // (如下圖) // (8) [1, "文字", true, {…}, 5, "杰倫", empty, "漂亮阿姨", name: "小明"] console.log(newArray[6]); // undefined console.log(newArray.length); // 8 (陣列長度) ``` ![](https://i.imgur.com/gNp0meq.png) :pencil2: **使用 for 迴圈 : 如何透過索引位置把資料一一陳列出來** 先宣告 i = 0 ; 即索引位置等於 0 當索引位置 < 陣列長度時,會依序地增加上去 ``` for (var i = 0; i < newArray.length; i ++) { console.log(newArray[i]) // 即取得陣列所有內容 } ``` --- ## JSON ### JSON 基本介紹 JSON 是個以純文字為基底去儲存和傳送簡單結構資料,可以透過特定的格式去儲存任何資料(字串,數字,陣列,物件),也可以透過物件或陣列來傳送較複雜的資料。一旦建立了您的 JSON 資料,就可以非常簡單的跟其他程式溝通或交換資料,因為 JSON 就只是個純文字格式。 * JSON 結構和物件很像 * JSON 的屬性一定會加「雙引號 " "」使之成為字串 ( JSON 裡的屬性一定是字串型式 ) * JavaScript 物件是以「單引號 ' '」撰寫 ; JSON 一定是「雙引號 " "」 (否則會跳錯) ``` var family = { name: '小明家', members: { father: '老爸', mom: '老媽', ming: '小明' }, } var json = JSON.stringify(family); // 把 family 物件轉為字串 console.log(json); // {"name":"小明家","members":{"father":"老爸","mom":"老媽","ming":"小明"}} ``` ### :pencil2: 範例 : 試著用原生 AJAX 撈取遠方資料並轉為陣列 **練習的 api : https://randomuser.me/api/** ``` var oReq = new XMLHttpRequest(); oReq.addEventListener('load', getData); oReq.open('get', 'https://randomuser.me/api/'); oReq.send(); function getData(){ console.log(oReq.responseText); // 抓到的資料為字串 console.log(typeof oReq.responseText); // string var data = JSON.parse(oReq.responseText);// 把字串轉為 JavaScript 的物件,方便開發上的運用 console.log(typeof data); // object } ``` ### :pencil2: 範例 : 試著用 jQuery 撈取遠方資料 Q : 為什麼使用框架會直接得到 JavaScript 物件,而不是 JSON 字串 ? A : 當使用框架,若傳入的是 JSON 格式,會自動轉為 JavaScript 物件,讓開發者少做轉檔步驟。 > 使用 jQuery 框架撈取遠方資料將直接是 object 載入 jQuery CDN : <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> (要放在 all.js 前面) ``` $.ajax({ url: "https://randomuser.me/api/", }).done(function (data) { console.log(data); console.log(typeof data); // object }); ``` 透過「NetWork」可看到「api/」這個檔案 → 點開右邊有「Response」為原本字串的型式 > JSON 並不是 JavaScript 的物件,是一個字串的型式,便於網路上做傳遞。 ![](https://i.imgur.com/vEcPDr5.png) --- ## 物件章節總結 ### :pencil2: 範例練習 1. 請問以下物件格式是否正確 ? ans : 可以使用 console.log 檢查資料是否正常呈現 > 物件可以使用**數字或字串**作為屬性的內容 > 所有屬性都是**字串**的格式 : 無論屬性是使用數字或字串,都屬於字串格式 ```typescript= var person = { name: '小明', age: 32, 1: '2', gender: 'male', 'interests': ['吃飯', '睡覺', '打動動'], greeting: function () { console.log('哈囉,你好'); }, '哈囉': function () { console.log('我是小明') } }; console.log(person); // (資料可正常呈現,物件格式正確) ``` 2. 試著執行物件中的兩個函式 ```typescript=15 person.greeting(); // 哈囉,你好 person['greeting'](); // 哈囉,你好 person['哈囉'](); // 我是小明 ``` 3. 運用以下陣列及 for 迴圈型式,執行 person 物件中的兩個函式 物件使用中括號 [ ] 取值 (中括號內可以插入變數) ```typescript=18 var personMethod = ['greeting', '哈囉']; for(var i = 0; i<personMethod.length; i++){ // console.log(personMethod[i]); // greeting 哈囉 (取出物件裡的屬性) person[personMethod[i]](); // 哈囉,你好 / 我是小明 (同時執行兩個函式) } ``` ### :pencil2: 範例練習- 物件傳參考的特性 ```typescript= // 參考位置示意圖如下左圖 var family = { // 新增物件,參考位置為 0x01 deposit: 100000, name: '小明家', members: { // 新增物件,參考位置為 0x02 father: '老爸', mom: '老媽', ming: '小明' } } ``` 1. jQuery.assign 會使用淺層複製把值取出 * <span class="red">**淺層拷貝也會宣告新的記憶體空間**</span> * 淺層拷貝會將第一層資料拷貝過來 2. 把值取出之前會先執行函式 changeName(family),參數為 family 傳入函式內 (參考位置 0x01 帶入 data),並修改 family 的值 3. family2 (使用淺層複製) 會接收原本 family 的值,產生新的記憶體空間為 0x03 > 物件是傳參考的概念,就算是傳遞函式的參數也是傳參考的概念 ```typescript=11 // 參考位置示意圖如下右圖 function changeName(data) { // 宣告 data 的變數,把參考位置 0x01 傳入 data.name = '杰倫家'; // 把傳入值的 name 改為 '杰倫家' (修改參考位置 0x01 的值) return data; // 再把 data 傳回來 (以傳參考的型式傳遞) } var family2 = jQuery.extend({}, changeName(family)); // 使用淺層複製將值取出 family2.members.jay = '杰倫'; // 在 family2.members 屬性裡加入 '杰倫' 的值 console.log(family, family2); ``` > 在第一層顯示相同資料(不同的參考路徑), 修改其中內容….另一個不會更動 > 在第二層 members 是相同的參考路徑,修改其中屬性….另一個也會更動 > ![](https://i.imgur.com/nKqfdM4.png) ![](https://i.imgur.com/Tf5oVAU.png) ```typescript=19 console.log('family.name', family.name); // 杰倫家 console.log('family.members.jay', family.members.jay); // 杰倫 console.log(family === family2); // false (family 和 family2 兩者以無關聯性) console.log(family.members === family2.members); // true (兩者的屬性 members 共用同一個參考位置) ``` --- ## 課後練習 ### :pencil2: 練習 1. 請問 a 會呈現什麼答案 ? ``` var a = {}; var b = a; var c = b = { number : 1}; c.name = '小明'; console.log(a); // {} console.log(b); // {number: 1, name: "小明"} console.log(b == c); // true ``` ![](https://i.imgur.com/iKiZINP.png) ### :pencil2: 練習 2. > forEach 把 family 陣列(物件)的屬性逐一取出後就直接 push 到新陣列中,屬於淺層複製。 ``` var family = [{ name : '小明家', members : { father : '父親', mom : '母親', ming : '小明', } }]; var array = []; family.forEach((item)=>{ // 淺層複製,相當於 for in 的語法 array.push(item); }) array[0].members.ming = 'casper'; console.log(family[0].members.ming); // casper console.log(array[0].members.ming); // casper console.log(family === array) // false (這兩者記憶體位子是不同的) ``` ![](https://i.imgur.com/PDy1EVG.png) ### :pencil2: 練習 3. ``` var array = ['1','2','3','4','5']; var array2 = array; array2[4] = '6'; console.log('array: ' + array[4]); // 6 console.log('array2: ' + array2[4]); // 6 console.log(array,array2); // ['1','2','3','4','6'] console.log(array==array2); // true ``` ### :pencil2: 練習 4. ``` var a = {x: 1}; var b = a = {y: 2}; console.log('第一次:'+ a.y); // 2 b.y = 3; console.log('第一次:'+ a.y); // 3 console.log('第一次:'+ b.y); // 3 ``` ![](https://i.imgur.com/BuBrlTK.png) ## :memo: 學習回顧 :::info * 使用陣列十字的方式定義陣列,直接插入值就可以了 * 取陣列的值 : array [索引位置] * 於陣列中插入新值 : array.push (值) * 陣列增加屬性內容,不會影響陣列長度 * 也可使用中括號 [ ] 新增值 : array[索引值]; 若中間有空的部分,會自動補上空值 ( 顯示 undefined ),也會影響陣列的長度 * 使用 array.length 的方法把陣列長度印出 * JavaScript 物件是以「單引號 ’ '」撰寫 ; JSON 一定是「雙引號 " "」 (否則會跳錯)( JSON 裡的屬性一定是字串型式 ) * 物件可以使用數字或字串作為屬性的內容 * 所有屬性都是字串的格式 * 無論屬性是使用數字或字串,都屬於字串格式 * jQuery.extend({}, object); 會使用淺層複製把值取出 * 淺層拷貝也會宣告新的記憶體空間 * 淺層拷貝會將第一層資料拷貝過來 * 物件是傳參考的概念,就算是傳遞函式的參數也是傳參考的概念 ::: <style> .red { color: red; } .green { color: green; } </style>