整篇會分成以下幾個部分:
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()
不需帶入任何參數
pop()
會回傳陣列被移除的元素。
如果是一個空陣列 (length
為 0),則回傳 undefined
。
會變動到原陣列
const names = ['Scarlett', 'Damien', 'Elisabeth', 'Jake']
const poppedName = names.pop()
console.log(poppedName)
// 'Jake'
console.log(names)
// ['Scarlett', 'Damien', 'Elisabeth']
names
names
呼叫 pop()
時會順著原型鏈拿到放在 Array.prototype
指向的 prototype 物件上的 pop()
methodpop()
呼叫時不需帶入任何參數,他會移除陣列的最後一個元素並將其回傳出來。names
被更動到,length
- 1, 最後一個元素被移除。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()
不會變動到原陣列並回傳一個指定區間的新陣列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
並指定 this
為 nmaesObj
pop()
會變動到原陣列,請小心使用,如果不想變動到原陣列可以使用 Array.prototype.slice
,可參考範例的 Example 2。
當原陣列為空陣列時,也就是 length
為 0 時,不會有任何作用,但會回傳 undefined
。
Array.prototype.pop()
this
轉型成一個 object 後指派給 O
O
的長度並指派給 len
len
等於 0,執行以下步驟O
的屬性 length
的值設為 0undefined
len
> 0len
- 1 轉為 Number 並指派給 newLen
newLen
轉為 Stzring 並指派給 index
O
的 index
屬性的值並指派給 element
O
的 index
屬性O
的屬性 length
的值設為 newLen
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 是如何做到這件事的。
最後,希望大家可以開心地使用各種咩色,體驗它帶給你的便利,祝大家歸剛沒煩惱。