by @zhangbao(zhangbao) #0105javascript
什麼是類數組呢?查看 Lodash _.isArrayLike(value)
函數的實現,得知參數 value
須符合下列條件:java
length
屬性length
屬性值是不大於 Number.MAX_SAFE_INTEGER
的天然數字符串就符合這個條件,說明它就是類數組。git
著名 JS 工具庫 Lodash 提供了一個工具函數:_.isArrayLike(value)
,檢查某個值是否爲類數組的。下面是官方給的用例:github
_.isArrayLike([1, 2, 3]);
// => true
_.isArrayLike(document.body.children);
// => true
_.isArrayLike('abc');
// => true
_.isArrayLike(_.noop);
// => false
複製代碼
_.isArrayLike
的實現細節下面是定義函數 isArrayLike
的地方:數組
import isLength from './isLength.js'
function isArrayLike(value) {
return value != null && typeof value !== 'function' && isLength(value.length)
}
複製代碼
首先檢查輸入的值:函數
value != null
:這個判斷使用的是 !=
,而非 !==
。令判斷結果爲 false
的值有兩個:null
和 undefined
。就是說,若是向 isArrayLike
函數傳入的值是 null
或 undefined
,那麼第一個判斷都未知足,直接返回 false
。💡 提示: 這裏引入了 JS 一個小怪癖的地方,就是規範中定義對於抽象相等算法(
==
內部執行的就是此算法):null == undefined
比較結果返回true
,天然null != undefined
的返回結果爲false
。工具
typeof value !== 'function'
:傳入值不能是函數,若是函數的話,也不算是類數組。isLength(value.length)
:最後檢查傳入值的 length
屬性,isLength(value.length)
返回值即 isArrayLike
的返回值。isLength
函數是用來幹什麼的?咱們來看下:oop
const MAX_SAFE_INTEGER = 9007199254740991
/** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * ... * */
function isLength(value) {
return typeof value === 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER
}
複製代碼
根據註釋,咱們知道 isLength
函數是用來檢查傳入值 value
是否爲有效長度。這裏的 MAX_SAFE_INTEGER
就等於 Number.MAX_SAFE_INTEGER
的值,這樣寫的目的估計是爲了效率,能少一步計算。ui
根據判斷邏輯,咱們知道所謂「有效的長度值」,是指值不大於 Number.MAX_SAFE_INTEGER
的天然數。
好比如下這些值,就不能算是有效的長度值:
isLength(Number.MIN_VALUE)
// => false。負數不是
isLength(Infinity)
// => false。無窮大不是
isLength('3')
// => false。字符串也不是
複製代碼
根據 isLength
方法的註釋說明:此種驗證方式是對規範中定義的抽象算法 ToLength
的寬鬆實現。下面是規範中的定義:
相較於規範中的定義,後者是包含類型轉換和參數值糾正邏輯的:
ToInteger(argument)
)+0
;無窮大轉爲 253 - 1 等。而這在 Lodash 中的實現中是沒有的,這就是爲何稱之爲「寬鬆實現」的緣由。
(完)