判断数组各种方式的优劣

发表于 2023-12-06 09:15:35
更新于 2024-04-18 13:33:37
Javascript

Array.isArray

简单,直观,对于真正的数组来说是最可靠的方法。

小缺点:不能判断修改成数组原型。

javascript
Array.isArray([]); // true

class EArray extends Array {}
Array.isArray(new EArray()); // true

const o = {
  [Symbol.toStringTag]: 'Array'
};
Array.isArray(o); // false

const notArray  = {};
Object.setPrototypeOf(notArray, Array.prototype);
Array.isArray(notArray); // false 这里其实也是需要注意的!


// 获取一个 iframe, 使用 iframe contentWindow 的 Array.isArray 判断
const isArray = iframe.contentWindow.Array.isArray;
isArray([1, 2, 3]); // true

[] instanceOf Array

缺点:

  • 依靠原型链来判断,但是原型可能会被改变。
  • iframe 下不准确。
javascript
[] instanceof Array; // true

class EArray extends Array {}
new EArray() instanceof Array; // true

const o = {
  [Symbol.toStringTag]: 'Array'
};
o instanceof Array; // false

// 获取一个 iframe, 使用 iframe contentWindow 的 Array.isArray 判断
const IfameArray = iframe.contentWindow.Array;
[1, 2, 3] instanceof IfameArray; // false

const notArray  = {};
Object.setPrototypeOf(notArray, Array.prototype);
notArray instanceof Array; // true

Object.prototype.toString.call

缺点:

  • 略显繁琐
  • Symbol.toStringTag 的存在,会造成误判
  • 修改了原型,也会误判
javascript
Object.prototype.toString.call([1,2,3]) === '[object Array]'; // true

class EArray extends Array {}
Object.prototype.toString.call(new EArray()) === '[object Array]'; // true

const o = {
  [Symbol.toStringTag]: 'Array'
};
Object.prototype.toString.call(o) === '[object Array]'; // true

const notArray  = {};
Object.setPrototypeOf(notArray, Array.prototype);
Object.prototype.toString.call(notArray) === '[object Array]'; // false

总结

现代 Javascript 中,应该使用 Array.isArray 来判断数组,能够满足正常多数的场景了。