对于js中数据路诶性的监测相信大家都不陌生,js中有很多方法可以提供给我们使用
但是有些方法可以用,但不严谨,今天就如何判断变量到底是不是数组来说明一下常用的方法
主流的判断方法 Array.isArray()
最好的方式是用ES的新方法Array.isArray()来判断
Array.isArray([]); // true
Array.isArray(['🍝']); // true
Array.isArray(new Array('🍝')); // true
浏览器支持情况
- chrome
- Firfox
- Safari
- Edge
- IE 9
旧浏览器兼容
ES5的数组原型上没有这个方法,所以需要重写Array的原型方法
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
或者你可以单独封装一个方法
function isArray(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
使用Lodash或者Underscore
我么可以借助第三的js方库来帮我们判断
Lodash
const array = ['🍝', '🍜', '🍲'];
const notArray = 'not array';
_.isArray(array); // true
_.isArray(notArray); // false
Underscore
const array = ['🍝', '🍜', '🍲'];
const notArray = 'not array';
_.isArray(array); // true
_.isArray(notArray); // false
为何不使用typeof
因为 Array 在js中的类型都是object 引用类型
typeof 'string'; // 'string'
typeof 100; // 'number'
typeof true; // 'boolean'
typeof false; // 'boolean'
typeof function() {}; // 'function'
typeof {}; // 'object'
typeof []; // 'object' <-- 😱
为何不使用Array.length
const array = ['🍝', '🍜', '🍲'];
array.length; // 3
数组的length属性确实可以帮助我们判断,但是字符串类型的数据也有length属性
const string = 'not array';
string.length; // 9
甚至一个对象也可能有一个length属性
const object = { length: 2 };
const array = ['🍝', '🍜', '🍲'];
typeof array === 'object' && Boolean(array.length); // true
typeof object === 'object' && Boolean(object.length); // true <-- 😱
为何不使用instanceof
const array = ['🍝', '🍜', '🍲'];
array instanceof Array; // true
这是我也看到人们参考的常见解决方案。 老实说,这是一个很好的方法。
但是,这有一个问题! 它不适用于多个上下文(例如框架或窗口)。
因为每一个frame都有不同的作用域,有自己的执行环境。
因此,它具有不同的全局对象和不同的构造函数。
因此,如果您尝试针对该frame的上下文测试数组,它将不会返回 true,而是会错误地返回为 false。
const frameNode = document.createElement('iframe'); // Create an iframe Element Node
document.body.appendChild(frameNode); // Append our frame element
const frameBrowser = window.frames[window.frames.length - 1]; // Access the frame from our current window
frameArray = frameBrowser.Array; // Access the "Array" object of the frame we created
// Create a new Array in our frame environment
const newFrameArray = new frameArray('🍝', '🍜', '🍲');
newFrameArray instanceof Array; // ❌ false
Array.isArray(newFrameArray); // ✅ true
为何不使用constructor
const array = ['🍝', '🍜', '🍲'];
array.constructor === Array; // true
这和instacneof存在同样的问题’
// ...
newFrameArray.constructor === Array; // ❌ false
Array.isArray(newFrameArray); // ✅ true