For the monitoring of the data path in JS, I believe everyone is familiar with it. There are many methods in JS that can be provided for us to use

But there are some methods that can be used, but they are not rigorous. Today, how do you determine whether a variable is an array or not

Array.isarray ()

The best way to do this is with ES’s new array.isarray () method


Array.isArray([]); // true
Array.isArray(['🍝']); // true
Array.isArray(new Array('🍝')); // true

Copy the code

Browser Support

  • chrome
  • Firfox
  • Safari
  • Edge
  • IE 9

Compatibility with older browsers

ES5 Array prototype does not have this method, so you need to rewrite the Array prototype method

if (!Array.isArray) {
  Array.isArray = function(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
  };
}
 

Copy the code

Or you can encapsulate a method separately


function isArray(arg) {
    return Object.prototype.toString.call(arg) === '[object Array]';
}

Copy the code

Use Lodash or Underscore

We can use the third JS library to help us judge

Lodash

const array = ['🍝'.'🍜'.'🍲'];
const notArray = 'not array';

_.isArray(array); // true
_.isArray(notArray); // false

Copy the code

Underscore

const array = ['🍝'.'🍜'.'🍲'];
const notArray = 'not array';

_.isArray(array); // true
_.isArray(notArray); // false

Copy the code

Why not use Typeof

Because Array types in JS are all object reference types

typeof 'string'; // 'string'
typeof 100; // 'number'
typeof true; // 'boolean'
typeof false; // 'boolean'
typeof function() {}; // 'function'
typeof {}; // 'object'

typeof []; / / 'object' < -- 😱
 

Copy the code

Why not use array.length

const array = ['🍝'.'🍜'.'🍲'];

array.length; / / 3

Copy the code

The length attribute of an array does help, but string data also has a length attribute

const string = 'not array';

string.length; / / 9

Copy the code

Even an object may have a length attribute

const object = { length: 2 };
const array = ['🍝'.'🍜'.'🍲'];

typeof array === 'object' && Boolean(array.length); // true
typeof object === 'object' && Boolean(object.length); / / true < -- 😱


Copy the code

Why not use Instanceof

const array = ['🍝'.'🍜'.'🍲'];

array instanceof Array; // true

Copy the code

This is a common solution THAT I also see people refer to. To be honest, this is a very good method.

But there’s a problem! It does not work in multiple contexts (such as frames or Windows).

Because each frame has a different scope, it has its own execution environment.

Therefore, it has different global objects and different constructors.

Therefore, if you try to test the array against the context of the frame, it will not return true, but will mistakenly return 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


Copy the code

Why not use constructor

const array = ['🍝'.'🍜'.'🍲'];

array.constructor === Array; // true

Copy the code

This has the same problem as Instacneof.

// ...

newFrameArray.constructor === Array; / / ❌ false

Array.isArray(newFrameArray); / / ✅ true
 

Copy the code