Day 08
如果你不是台灣的國民,就不能在台灣投票
Javascript 是弱型別語言,也因為這個特性,在處理資料時 JavaScript 很可能的很好心,一不小心就把資料自動轉型成另一個資料型態了,所以為了避免在使用陣列內建方法或處理陣列時出現錯誤,常常會使用許多方法來判別是否為陣列。如果元素不是陣列,就無法使用陣列專用的函式或做些陣列的處理,因此才會有確認某元素的原型是陣列的需要。
陣列 Array 在 JavaScript 裡的型別是object
,這點可以透過 typeof 這個運算符回傳的資訊,來確認某一資料是否為陣列。但是,在物件裡的某一元素是否為陣列,又該怎麼判別? 以下有幾種方法:
判別變數是否為陣列
這邊有四個同是陣列,但不同形態內容的元素,還有一個非陣列的物件變數,我們可以拿它們來測試。
1 | // 陣列常値 // 數字陣列 |
isArray 小而美
最簡單的陣列判斷語法 isArray,用的是內建 Array 物件中的 isArray,是個 ES5 的標準方法:Array.isArray(variable)
1 | Array.isArray(arr1); // true |
constructor === Array 輕而巧
使用constructor
,這個是在 Chrome 瀏覽器中效能最佳的判斷方法,它是直接用物件的建構式來判斷:variable.constructor === Array
1 | arr1.constructor === Array; // true |
判別物件中的陣列
constructor === Array
與上方一個相同,只是針對物件中的陣列來使用,如果要判別物件中的其中屬性是否為陣列,可以先判斷這個屬性是否存在,再繼續判斷這個值是否為陣列,我們以物件型態的變數來測驗,如下:variable.value && variable.value.constructor === Array
1 | const me = { |
instanceof 物件的實例
先來看看 MDN 怎麼解釋:MDN instanceofinstanceof
運算符用於測試建構式函式的 prototype 屬性,是否出現在物件的原型鏈中的任何位置,也就是說instanceof
運算符是用於判斷是否為某個建構式new
的實例,優點為語法簡潔清楚。
但是缺點還是有的,雖然只要是在原型鏈上面的類別,都會回傳true
,但是建構是有可能因為某些原因而被修改,改變之後的值很有可能不存在於原型鏈上,這時判別回傳得到的值就會成為false
。
1 | function fnuc() {} |
instanceof
不只可以判別陣列,也可以拿來判別其他的型別,如string
。
1 | var arr5 = [1, 2, 3]; |
instanceof
有個缺點,就是處理的window
或iframe
時的變數會失效,詳細的解說在MDN有較詳細的說明。
toString.call
==推薦使用==
網路上推薦這種方式判別的頗多,原因應該是這種方式是所有情況都可以正確判別的一種,且可適用各種狀況,也可以判斷陣列以外的其他特別物件,唯一缺點是效率最差。
在 JavaScript: The Definitive Guide, 6th Edition 書中有提到,Array.isArray 其實就是用這個方式實作的。Object.prototype.toString.call(variable) === '[object Array]'
網路上也有人寫成一支判斷陣列終極解決方案,先用typeof
判別,再確認瀏覽器支不支援這個判別方法,如果不支援,就用另一種方式判別。
1 | const arr6 = [1, 2, 3]; |
用哪一種?
這幾個方式的選擇,網路上的前輩建議是==只要學最後一種==就行了(就是最後一種),可以正確判斷並應用在各種情況為首要條件,有時候正確性比效能快更為重要,更何況它其實是萬用的,除了陣列之外也可以用於其它的判斷情況。雖然它的語法對初學者來說,可能無法在此時完全理解 在說我嗎?,不過就先知道要這樣用就行了。
寫完才發現這篇更詳細的介紹,有興趣的可以轉台過去看,真的很詳細,推~
如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~