iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

閱讀說明

整篇會分成以下幾個部分:

  • 使用時機
  • 語法
  • 範例
  • 注意事項
  • ECMAScript
  • 結論

pop 這個 method 的全寫應該是 Array.prototype.pop,有興趣可以看 Day 2 的介紹,這邊會直接使用 pop() 作為替代。

Array method 有不少會使用到 callback function,如果尚不熟悉的話,可以看 Day 2 的介紹。

範例使用的 callback 都會使用箭頭函式做介紹,如果尚不熟悉的話可以參考 MDN 的介紹。

最後會透過分析 ECMAScript 來驗證是否有吻合,如果覺得 ECMAScript 有點艱澀難懂,我們在 Day 4 、Day 5 有介紹其相關術語可以幫助閱讀。


使用時機

當你需要移除陣列的最後一個元素時。

當陣列為空陣列時 (length 為 0)回傳 undefined

你同時可能會想到的其他方法:

  • shift() - 移除陣列的第一個元素
  • slice() - 回傳一個指定區間的新陣列

語法

pop()

參數

不需帶入任何參數

Return Value

pop() 會回傳陣列被移除的元素。

如果是一個空陣列 (length 為 0),則回傳 undefined

Mutability

會變動到原陣列


範例

Example 1 - 基礎用法

const names = ['Scarlett', 'Damien', 'Elisabeth', 'Jake']

const poppedName = names.pop()
console.log(poppedName)
// 'Jake'

console.log(names)
// ['Scarlett', 'Damien', 'Elisabeth']
  • 宣告了一個包含 4個元素的陣列實例 - names
  • names 呼叫 pop() 時會順著原型鏈拿到放在 Array.prototype 指向的 prototype 物件上的 pop() method
  • pop() 呼叫時不需帶入任何參數,他會移除陣列的最後一個元素並將其回傳出來。
  • 原陣列 names 被更動到,length - 1, 最後一個元素被移除。

Example 2 - pop() vs slice()

const fruits = ['kiwi', 'cherry', 'jujube', 'guava']

const poppedFruit = fruits.pop()

console.log(poppedFruit)
// guava
console.log(fruits)
// ['kiwi', 'cherry', 'jujube']

const seafoods = ['oyster', 'shrimp', 'salmon', 'tuna']

const slicedSeafood = seafoods.slice(-1)
console.log(slicedSeafood)
// ['tuna']
console.log(seafoods)
// ['oyster', 'shrimp', 'salmon', 'tuna']
  • pop() 會變動到原陣列並回傳被移除的元素
  • slice() 不會變動到原陣列並回傳一個指定區間的新陣列

Example 3 - 將 pop() 使用在非陣列的物件

const namesObj = {
	0: 'Emma',
	1: 'Spencer',
	2: 'Jed',
	length: 3
}

const poppedName = Array.prototype.pop.call(namesObj)

console.log(poppedName)
// 'Jed'

console.log(namesObj)
// {
//	0: 'Emma',
//	1: 'Spencer',
//	length: 2
// }
  • 創造了一個類陣列的物件,擁有 length 屬性及從 0 開始的索引屬性
  • 借用 Array.prototype.pop 並指定 thisnmaesObj

注意事項

pop() 會變動到原陣列,請小心使用,如果不想變動到原陣列可以使用 Array.prototype.slice,可參考範例的 Example 2。

當原陣列為空陣列時,也就是 length 為 0 時,不會有任何作用,但會回傳 undefined


ECMAScript

演算法步驟

12.1

  1. this 轉型成一個 object 後指派給 O
  2. 取得 O 的長度並指派給 len
  3. 如果 len 等於 0,執行以下步驟
    a. 將 O 的屬性 length 的值設為 0
    b. 回傳 undefined
  4. 否則執行以下步驟
    a. 斷言 len > 0
    b. 將 len - 1 轉為 Number 並指派給 newLen
    c. 將 newLen 轉為 Stzring 並指派給 index
    d. 取得 Oindex 屬性的值並指派給 element
    e. 刪除 Oindex 屬性
    f. 將 O 的屬性 length 的值設為 newLen
    g. 回傳 element

粗略解析

演算法的前 2 個步驟都是用來做一些前置處理,包括轉型、確認長度等...。

其中如果陣列的長度為 0,便將陣列的長度設為 0,並且回傳 undefined,表示這個陣列沒有元素可被移除,並且長度不變。

在 ECMAScript 的出現的 Assert (斷言) 代表當前的這個敘述會被判斷真假,且一定為真,所以步驟 4 裡的 a ,len 一定會大於 0。

出現 ? 的地方代表有可能會丟出錯誤,所以整個演算法有 6 處有機會丟出錯誤,例如步驟 4 的 f, Set() 會在屬性設值失敗且第 4 個 Throw 參數為 true 時丟出一個 TypeError

如果出現 ! ,則代表這個 abstract operation 絕對不會丟出錯誤,例如步驟 4 的 c, ToString() 它會在參數是一個 Symbol 時丟出一個 TypeError,但我們確定丟進去的是一個 Number (F(k)),因此不會有丟出錯誤的可能。

ECMAScript 其實並沒有規定使用 pop() 的物件必須是一個陣列,從步驟 1 跟 Note 2 可以看得出來,可以參考範例的 Example 3。


結論

pop() 可能是大家開始學習 JavaScript 時最早接觸的 Array method,因為它既不需要參數看起來又直覺簡單,但實際上它背後隱藏著不少東西可以挖掘,有空可以看看 ECMAScript 是如何做到這件事的。

最後,希望大家可以開心地使用各種咩色,體驗它帶給你的便利,祝大家歸剛沒煩惱。


參考資源


上一篇
Day 11 咩色用得好 - Array.prototype.map
下一篇
Day 13 咩色用得好 - Array.prototype.reduce (新手摧毀者)
系列文
咩色用得好,歸剛沒煩惱 - 從 ECMAScript 偷窺 JavaScript Array method30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言