Day20 | JS陣列與物件常用的方法

❒ 陣列寫入、新增、刪除資料

➊ 透過索引位置 取代原值、新增、取值

  1. 取代原值 Array[n] = 新值;

    • 「 索引位置 」為每個元素的位置,從第 0 筆開始,如下方陣列範例中的索引位置分別為:第 0 筆為 'A',第 1 筆為 'B',第 2 筆為 'C'

      1
      let newArray = ['A', 'B', 'C'];
    • n 帶入索引位置,新值為要取代陣列中原有的內容。

      1
      2
      3
      4
      // 把索引位置1的值取代成 B2
      let newArray = ['A', 'B', 'C'];
      newArray[1] = 'B2';
      console.log(newArray); // ['A', 'B2', 'C']
  2. 在陣列中新增值 Array[n] = 值;

    • 此方式會新增至陣列中第 n 個索引位置

      1
      2
      3
      let newArray = ['A', 'B', 'C'];
      newArray[3] = 'D';
      console.log(newArray); ['A', 'B', 'C', 'D']
    • 如果陣列沒有依照索引順序新增,跳過幾個索引位置去新增資料,JS 會自動在這些位置補上空值 undefined,這會影響到陣列長度 ( 那些空值也會加入到索引長度中 )。

  3. 取陣列中第 n 筆的值 Array[n]

    1
    2
    let newArray = ['A', 'B', 'C'];
    console.log(newArray[2]); //C

➋ 新增 push()

新增至陣列中的最後一筆資料。

1
2
3
let array = [0, 1, 2];
array.push(5);
console.log(array); // [0, 1, 2, 5]

➌ 新增 unshift()

新增至陣列中的索引位置第 0 筆資料。( 新增至陣列最開始那筆 )

1
2
3
let array = [0, 1, 2];
array.unshift(5);
console.log(array); // [5, 0, 1, 2]

❹ 刪除 pop()

刪除陣列中最後一筆索引資料

1
2
3
let array = [0, 1, 2];
array.pop();
console.log(array); // [0, 1]

❺ 刪除 shift()

刪除陣列中第 0 筆索引資料

1
2
3
let array = [0, 1, 2];
array.shift();
console.log(array); // [1, 2]

❻ 刪除 splice(參數1,參數2)

  • 刪除陣列中指定資料
  • 參數 1 → 陣列中起始位置
  • 參數 2 → 從參數 1 的位置要往後刪除幾筆資料,包含參數 1 本身。
1
2
3
let array = [5, 8, 2];
array.splice(1,2);
console.log(array); // [5]

❼ 更多陣列語法

❒ 物件讀取、新增、修改、刪除方式

➊ 讀取物件的值 - 點記法 object.屬性

1
2
3
4
5
6
let home = {
mother: "Linda",
father: "David",
};

console.log(home.mother); //Linda

➋ 讀取 & 新增物件的值 [''] 括號+字串方式

通常情況下會使用 . 取值,但某些情況無法用 . 取值,例如:屬性為數字開頭時 ( 物件的屬性不論是否為數字都會視為字串 )、讀取變數的情況下、JSON 格式有些屬性名稱會使用 "isName" 字串方式包起,就會需要使用括號方式 [] 來讀取或新增。

1
2
3
4
5
6
7
8
9
10
11
12
13
let obj = {
myName: "王小花",
};
//讀取物件屬性
console.log(obj['myName']); //王小花

//新增物件屬性
obj['key'] = 'value';
console.log(obj); //{myName: "王小花", key: "value"}

//讀取變數
let a = 'myName';
console.log(obj[a]);
1
2
3
4
5
6
7
8
// 字串取值
const family = {
dog: 2,
callFamily: function() {
console.log('呼叫家庭群組');
}
}
family['callFamily'](); // 印出 呼叫家庭群組

➌ 新增物件屬性 object.屬性 = 屬性值;

1
2
3
let home = {};
home.mother = "Linda";
console.log(home); //{mother: "Linda"}

❗注意:不能在物件下於未定義的屬性新增屬性值,會顯示錯誤訊息 Uncaught TypeError。可參考筆記

❹ 修改物件值 object.要修改的屬性名 = 屬性值;

1
2
3
4
5
6
7
let home = {
mother: "Linda",
father: "David",
dogName: "啾咪",
};
home.dogName = "小啾";
console.log(home.dogName); //小啾

❺ 刪除物件資料 delete object.屬性;

1
2
3
4
5
6
7
let home = {
mother: "Linda",
father: "David",
dogName: "啾咪",
};
delete home.dogName;
console.log(home.dogName); //{mother: "Linda", father: "David"}

❒ closest()

e.target.closest(selector)

  • 選取到指定的選擇器 selector 最近的元素

  • 練習 codepen

  • 程式碼

    1
    2
    3
    <input type="text" class="typeContent" placeholder="請填入文字">
    <input type="button" class="sendBtn" value="送出">
    <ul class="list"></ul>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    const typeContent = document.querySelector(".typeContent");
    const sendBtn = document.querySelector(".sendBtn");
    const list = document.querySelector(".list");
    let data = [];
    // 1.渲染畫面
    function render(arr){
    let str = "";
    arr.forEach((item) => {
    str += `<li data-id="${item.id}">${item.content}</li>`
    })
    list.innerHTML = str;
    }
    // 2.新增資料
    sendBtn.addEventListener("click", (e) => {
    if(typeContent.value.trim() !== ""){
    data.push({
    id: new Date().getTime(),
    content: typeContent.value.trim(),
    });
    typeContent.value = "";
    }
    render(data);
    })

    // 3.選取 li 的 id
    // 使用 closest 印出 li 的 id
    list.addEventListener("click", (e) => {
    // 取出離我們點擊到最近的 li 的 data-id
    let listId = e.target.closest("li").dataset.id;
    console.log(listId);
    })

線上課程


element.closest(selectors)

  • 參數 selectors 為指定的選擇器。
  • 用來選取特定選取器且離當前元素最近的祖先元素 ( 也可以是當前元素本身 ),如果匹配不到就返回 null

實作範例

  • 程式碼

    1
    2
    3
    4
    5
    6
    7
    <article>
    <div id="div-01">Here is div-01
    <div id="div-02">Here is div-02
    <div id="div-03">Here is div-03</div>
    </div>
    </div>
    </article>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    const el = document.getElementById('div-03');

    const r1 = el.closest("#div-02");
    // 返回 id 为 div-02 的那个元素

    const r2 = el.closest("div div");
    // 返回最近的拥有 div 祖先元素的 div 祖先元素,这里的话就是 div-03 元素本身

    const r3 = el.closest("article > div");
    // 返回最近的拥有父元素 article 的 div 祖先元素,这里的话就是 div-01

    const r4 = el.closest(":not(div)");
    // 返回最近的非 div 的祖先元素,这里的话就是最外层的 article

參考文章 : MDN - Element.closest()

❒ 補充 slice(參1,參2)

  • 回傳一個新陣列物件,為原陣列選擇的 begin 至 end(不含 end)部分的淺拷貝(shallow copy)。( 可用來預設每頁顯示 x 筆資料,用來生成每頁的資料。 範例 )
  • slice(參1,參2)
    • 參數 1 ,是要從哪個索引值開始切
    • 參數 2 ,指要在哪一個索引值結束,但要注意參數 2 如果是 3 那就會取到索引值 2 就停止。
    • 參數為負數,會從陣列的尾值開始往前算。如果這個負數超過陣列的長度,slice() 就會把所有能給我們都給出來。

範例

1
2
3
4
5
6
const alphabet =['a','b','c','d','e'];
console.log(alphabet.slice(1,3));
console.log(alphabet.slice(1));
console.log(alphabet.slice(-4));
console.log(alphabet.slice(-3));
console.log(alphabet.slice(-10));
  • 答案
    1. 從第 1 個索引值 b 開始,到第 3 個索引值停止也就是取到索引值 3 的前一個 c。
      ['b', 'c']
    2. 回傳一個新陣列,從第一個索引值開始做淺層拷貝。
      ['b', 'c', 'd', 'e']
    3. 變數 alphabet 有五個值 alphabet(5+(-4)) → 拿掉第一個值 a
      ['b','c','d','e']
    4. 尾值 'e' 往前算 3 個值 : 'e''d''c'
      ['c','d','e']
    5. 負數超過陣列的長度,slice() 就會把所有能給我們都給出來。
      ['a','b','c','d','e']

參考資訊