js如何判斷變量是否為數組 5個判斷數組類型的實用技巧分享

判斷JavaScript變量是否為數組的最推薦方法是使用Array.isarray()。1. array.isarray():最推薦的方法,簡單直接,跨frames/windows安全,兼容現代瀏覽器(不支持舊版ie);2. instanceof:存在多frames/windows下不可靠、原型鏈可能被修改的問題;3. Object.prototype.tostring.call():通用可靠,適用于所有類型,但代碼稍長;4. constructor:易受constructor屬性被修改的影響;5. 鴨子類型:靈活但不夠嚴謹,可能誤判非數組對象

js如何判斷變量是否為數組 5個判斷數組類型的實用技巧分享

判斷JavaScript變量是否為數組,核心在于區分數組和其他對象類型。有多種方法可以實現這一點,但每種方法都有其適用場景和局限性。選擇哪種方法取決于你的具體需求和兼容性考慮。

js如何判斷變量是否為數組 5個判斷數組類型的實用技巧分享

  1. Array.isArray():這是最推薦的方法,簡單直接且兼容性良好(除了較舊的IE版本)。

    js如何判斷變量是否為數組 5個判斷數組類型的實用技巧分享

  2. instanceof:雖然常用,但存在一些問題,特別是在有多個frames或windows的情況下。

  3. Object.prototype.toString.call():通用且可靠,但稍微冗長。

    js如何判斷變量是否為數組 5個判斷數組類型的實用技巧分享

  4. constructor:在某些特殊情況下可能不準確。

  5. 鴨子類型(Duck Typing):通過檢查變量是否具有數組的特定屬性和方法來判斷,但不夠嚴謹。

Array.isArray() 的優勢與局限

Array.isArray() 方法是ES5引入的,用于確定傳遞的值是否是一個 Array。它解決了 instanceof 在多 frames 或 windows 環境下的問題,因為每個 frame 都有自己的執行上下文和不同的 Array 構造函數

優勢:

  • 簡單易用:Array.isArray(myVar)。
  • 跨 frames/windows 安全:能夠正確識別來自不同 frames 或 windows 的數組。
  • 廣泛支持:現代瀏覽器都支持,對于不支持的舊版本瀏覽器,可以使用 polyfill。

局限性:

  • 舊版 IE 不支持:需要使用 polyfill 來兼容。

示例:

Array.isArray([1, 2, 3]);  // true Array.isArray({Length: 3}); // false Array.isArray(document.getElementsByTagName('div')); // false (雖然類似數組,但不是真正的數組)  // Polyfill for older browsers if (!Array.isArray) {   Array.isArray = function(arg) {     return Object.prototype.toString.call(arg) === '[object Array]';   }; }

instanceof 操作符的潛在陷阱

instanceof 運算符用于檢測構造函數的 prototype 屬性是否出現在對象的原型鏈中的任何位置。對于數組來說,它檢查變量的原型鏈上是否存在 Array.prototype。

優勢:

  • 簡單直觀。

局限性:

  • 在多 frames 或 windows 環境下不可靠:如果頁面包含多個 frames,每個 frame 都有自己的全局執行上下文,以及不同的 Array 構造函數。這意味著一個 frame 中的數組,在另一個 frame 中使用 instanceof 檢測時,可能會返回 false。
  • 原型鏈可能被修改:如果 Array.prototype 被修改,instanceof 的結果可能會不準確。

示例:

let arr = [1, 2, 3]; arr instanceof Array; // true  let iframe = document.createElement('iframe'); document.body.appendChild(iframe); let iArray = iframe.contentWindow.Array; let arr2 = new iArray(1, 2, 3); arr2 instanceof Array; // 在某些情況下可能為 false,取決于瀏覽器和環境

Object.prototype.toString.call() 的可靠性

Object.prototype.toString 方法返回一個表示該對象的字符串。當使用 call() 方法調用時,可以指定 this 的值,從而獲取任何變量的類型信息。對于數組,它會返回 “[object Array]”。

優勢:

  • 通用且可靠:適用于所有類型的變量,包括 NULLundefined
  • 跨 frames/windows 安全:不受 frames 和 windows 的影響。

局限性:

  • 稍微冗長:相對于 Array.isArray(),代碼稍長。

示例:

Object.prototype.toString.call([1, 2, 3]);   // "[object Array]" Object.prototype.toString.call(new Date());  // "[object Date]" Object.prototype.toString.call(null);       // "[object Null]" Object.prototype.toString.call(undefined);  // "[object Undefined]"  function isArray(obj) {   return Object.prototype.toString.call(obj) === '[object Array]'; }

constructor 屬性的注意事項

每個 JavaScript 對象都有一個 constructor 屬性,指向創建該對象的構造函數。對于數組來說,它通常指向 Array 構造函數。

優勢:

  • 簡單易懂。

局限性:

  • constructor 屬性可能被修改:如果對象的 constructor 屬性被修改,那么使用這種方法判斷數組類型可能會出錯。
  • 在某些特殊情況下可能不準確:例如,當使用 Object.create(null) 創建對象時,該對象沒有 constructor 屬性。

示例:

let arr = [1, 2, 3]; arr.constructor === Array; // true  let obj = Object.create(null); // obj.constructor === undefined  function MyArray() {} MyArray.prototype = []; let myArray = new MyArray(); myArray.constructor === MyArray; // false, 因為原型被重寫

鴨子類型(Duck Typing)的適用場景

鴨子類型是一種動態類型判斷的方法,它不關心對象的實際類型,只關心對象是否具有特定的屬性和方法。對于數組來說,可以檢查變量是否具有 length 屬性,以及是否可以通過索引訪問元素。

優勢:

  • 靈活:可以判斷類似數組的對象,例如 arguments 對象和 dom 集合。

局限性:

  • 不夠嚴謹:可能會誤判不是數組的對象。例如,一個具有 length 屬性和數字索引屬性的對象,會被誤判為數組。

示例:

function isArrayLike(obj) {   return typeof obj === 'object' &&          typeof obj.length === 'number' &&          obj.length >= 0 &&          !isNaN(obj.length) &&          (obj.length === 0 || (typeof obj[obj.length - 1] !== 'undefined')); }  isArrayLike([1, 2, 3]);            // true isArrayLike({length: 3, 0: 'a', 1: 'b', 2: 'c'}); // true isArrayLike(document.getElementsByTagName('div'));   // true (HTMLCollection) isArrayLike('hello');               // false

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享