javascript 判斷是否爲數組 isArray()

JavaScript 在類型判斷上確實是有比較多的坑,在不使用 ES5 的 Array.isArray() 的狀況下,如何判斷呢?javascript

首先放棄typeof

javascript 弱類型的語言就是有比較多的坑,單純的typeof 是很無力的。因此用它來判斷數組確定是不行的。java

typeof 1    // number
    typeof undefined  // undefined
    typeof null // object
    typeof []   // object
    typeof {}   //object
    typeof function (){} // function

那麼言歸正傳正傳,該如何判斷。數組

思路一:length 屬性判斷

Array 對象都是有length 屬性的,可不能夠判斷lengthapp

function isArray(array) {
      return (typeof array === 'object' && typeof array.length === 'number')
  }

與這個相似的是函數

function isArray(array) {
      return (typeof array === 'object' && !isNaN(array.length))
  }

可是這個存在的問題是,對於有length屬性的對象,則會出現判斷失誤的問題
好比:.net

var fakeArray = {
        length: 10,
        value: 'Fake Array'
    }

思路二:對Array實例對象的原型進行判斷。

var arr = [1, 2, 3]
    arr instanceof Array
    
    // constructor 指向了原型
    arr.constructor === Array

但在多iframe的狀況下,因爲每一個iframe 是一個獨立的環境,它們之間不不共享原型鏈,則經過原型進行判斷會出現錯誤prototype

var iframe = document.createElement('iframe')
document.body.appendChild(iframe)
xArray = window.frames[window.frames.length-1].Array
var arr = new xArray(1,2,3) // [1,2,3]

// 正確的判斷
Array.isArray(arr)  // true
// 有問題的判斷
arr instanceof Array // false
arr.constructor === Array // false

思路三: Object.prototype.toString.call() 方法

適用於全部環境,只支持原生的對象,Object的toString()方法不能檢測非原生構造函數的構造函數名。開發人員自定義的任何構造函數都將返回[object Object]。在任何值上直接調用Object的原生toString()方法,都會返回[object NativeConstrctorName]格式的字符串,每一個類內部都有一個class屬性,這個屬性中就指定了上述字符串中構造函數名。
 code

Object.prototype.toString.call(array) === '[object Array]'

不過,上面的方案也存在必定問題,在ES6 中這樣的判斷能夠被欺騙htm

var obj = {};
    // ES6 Symbol
    obj[Symbol.toStringTag] = 'Array';
    // true
    console.log(isArray(obj));

結論

在ES5 以後,就老老實實用Array.isArray 來判斷,ES5以前能夠使用上面pollyfill。對象

if (!Array.isArray) {
        return Object.prototype.toString.call(array) === '[object Array]';
    }
結論延伸

以此延伸,那麼判斷其餘類型就能夠使用相似的方法

var is = function (obj,type) { 
        return (type === "Null" && obj === null) || 
            (type === "Undefined" && obj === void 0 ) || 
            (type === "Number" && isFinite(obj)) || 
            Object.prototype.toString.call(obj).slice(8,-1) === type; 
    }

參考:

1.Javascript isArray 數組類型檢測函數

2.JavaScript數組的isArray方法實現

相關文章
相關標籤/搜索