理解Array.prototype.slice.call()

晚上看張鑫旭老師的一篇文章,發現[].splice.call()這樣的用法,很感興趣,由於昨天剛寫完一篇關於call方法的博客《一文讀懂js中的call和apply》(如下簡稱「《call》」),想一探究竟,也正好加深對call的理解。php

基礎:

  1. slice()方法能夠從已有的數組中返回選定的元素,語法:array.slice(start, end),截取array中第start位到第end位之間的部分,範圍:[start, end);
  2. slice()的參數能夠省略,省略時默認從0開始,一直到最後一位,也就是返回所有;
  3. call和apply的做用都是在特定做用域中調用函數,例如:程序員.編程.call(外賣員)就是在外賣員做用域中調用程序員的編程方法,即外賣員編程。

探索:

張老師[].slice.call(eleRadios)這麼寫是想讓eleRadios調用數組的原生方法slice()從而轉換成數組格式,那麼eleRadios自己不是數組嗎?非得繞這麼一大圈?下面貼出他的部分代碼(完整版點擊這裏):ios

// 已刪除部分無關代碼
<input type="radio" value="default" checked>
<input type="radio" value="red">
<input type="radio" value="green">

var eleRadios = document.querySelectorAll('input[type="radio"]');
[].slice.call(eleRadios).forEach(function (radio) {
    radio.addEventListener('click', function () {
        // 略
    });
});

經過document.querySelectorAll獲取頁面上全部type等於「radio」的input的節點集合eleRadios,接着對[].slice.call(eleRadios)進行forEach遍歷,給其中每一個子元素添加click點擊事件。爲何不能直接調用forEach方法——就像這樣eleRadios.forEach()?看來eleRadios真不是數組?因而我在頁面上的調試工具console中測試了一下,發現猜測是對的:程序員

經過打印,得知eleRadios是NodeList類型,爲了再次驗證它與數組的關係,我還使用instanceof的方式進行檢測,以及看看它可否調用forEach方法,結果一目瞭然:不是數組,天然不能調用數組的forEach方法。web

原理:

如今就清楚了,爲了能遍歷這個NodeList類型的eleRadios,就使用call方法啦:在eleRadios這個做用域中調用數組的slice方法,以轉化成數組類型,而後調用forEach方法實現遍歷。編程

由於[]是Array的實例,因此也能夠寫成[].slice.call()數組


2019年12月25日聖誕節補充app

類數組轉數組的ES6寫法:wordpress

const arr = Array.from(eleRadios)
const arr = [...eleRadios]
相關文章
相關標籤/搜索