iT邦幫忙

2021 iThome 鐵人賽

DAY 16
1
Modern Web

初學者跪著學JavaScript系列 第 16

初學者跪著學JavaScript Day16 : 陣列Array 迭代的小小秘密

  • 分享至 

  • xImage
  •  

一日客語:中文:早安 客語:anˋzoˋ安走
前提:在學習Array.methods時會想知道他是如何迭代Array內的元素,才知道會有這一些稍微不同的迭代差異。

find、filter會迭代array,像是這樣:

let a = ['apple', , , 'egg'];

a.find(function (value, index, array) {
    console.log('index:', index);
    console.log('value:', value);
    console.log('array:', array);
});
//結果
//index: 0
//value: apple
//array: [ 'apple', <2 empty items>, 'egg' ]
//index: 1
//value: undefined
//array: [ 'apple', <2 empty items>, 'egg' ]
//index: 2
//value: undefined
//array: [ 'apple', <2 empty items>, 'egg' ]
//index: 3
//value: egg
//array: [ 'apple', <2 empty items>, 'egg' ]

會把array元素一個個帶進function

a = [0, 1, 2, 3, 4, 5, 6]

有想過在把a[4]元素帶進CallBack function 的時候把後面元素刪掉會發生什麼事嗎?

find版本

執行方式:a[4]帶入callBack function 帶入時把a[5]元素刪除

let a = [0, 1, 2, 3, 4, 5, 6];
a.find(function (value, index) {
    console.log('index:', index, 'value:', value);
    if (index == 4) {
        delete a[5];
    }
});
//結果
//index: 0 value: 0
//index: 1 value: 1
//index: 2 value: 2
//index: 3 value: 3
//index: 4 value: 4
//index: 5 value: undefined
//index: 6 value: 6

把元素迭代進function 事前會先把array.length長度算好,知道跑幾次

就算把最後一個元素刪除也是這樣情況

let a = [0, 1, 2, 3, 4, 5, 6];
a.find(function (value, index) {
    console.log('index:', index, 'value:', value);
    if (index == 5) {
        delete a[6];
    }
});
//index: 0 value: 0
//index: 1 value: 1
//index: 2 value: 2
//index: 3 value: 3
//index: 4 value: 4
//index: 5 value: 5
//index: 6 value: undefined

因為一開始迭代長度已經算好,迭代時仍會找6

filter版本

會發現filter的index居然沒有6!!和find不一樣結果

let a = [0, 1, 2, 3, 4, 5, 6];
a.filter(function (value, index) {
    console.log('index:', index, 'value:', value);
    if (index == 5) {
        delete a[6];
    }
});
//index: 0 value: 0
//index: 1 value: 1
//index: 2 value: 2
//index: 3 value: 3
//index: 4 value: 4
//index: 5 value: 5

原因(aka小小秘密)

因此看一下ECMA 如何定義
ECMA 比較圖:

演算法中filter方法多了HasProperty的確認機制,在find方法不會確認key為6的值存不存在而filter方法會~

像是map、reduce、forEach等常見方法也會確認HasProperty

不過在迭代時delete自己的property應該很少人這樣使用,所以我自己把這個當作一個小小小小小的的知識


更詳細Array methods 使用方式可以看看隊友寫的:
傳送門
就決定是你了 - 陣列系列I
就決定是你了 - 陣列系列 II
就決定是你了 - 陣列系列III

感謝大神!
Cathy大大的神來之手 CathyShen-網頁阿尼尛,到底是在幹尛

資料參考:
ECMA262


上一篇
初學者跪著學JavaScript Day15 : 陣列中沒被定義的空值(empty item)
下一篇
初學者跪著學JavaScript Day17: 物件:new Set()
系列文
初學者跪著學JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Chiahsuan
iT邦新手 4 級 ‧ 2021-10-01 15:38:03

/images/emoticon/emoticon02.gif/images/emoticon/emoticon41.gif
謝謝Wendy大大的安利和校稿XD

wendy iT邦新手 2 級 ‧ 2021-10-01 18:58:48 檢舉

也謝謝幫我校稿

0
Chris
iT邦新手 3 級 ‧ 2021-10-01 17:13:11

圖很帥

看更多先前的回應...收起先前的回應...
wendy iT邦新手 2 級 ‧ 2021-10-01 18:58:10 檢舉

饅頭大人幫我付一下版權費/images/emoticon/emoticon07.gif

Chris iT邦新手 3 級 ‧ 2021-10-01 19:48:31 檢舉

/images/emoticon/emoticon63.gif

CathyShen iT邦新手 4 級 ‧ 2021-10-04 10:50:56 檢舉

要是 wendy 沒有得獎,就要準備支付這張圖的版權費了
wendy 瑟瑟發抖 (˘•ω•˘)

wendy iT邦新手 2 級 ‧ 2021-10-04 16:08:40 檢舉

太難了~已發抖 /images/emoticon/emoticon63.gif

我要留言

立即登入留言