How to efficiently check if variable is Array or Object (in NodeJS & V8)?
Solution 1
All objects are instances of at least one class – Object
– in ECMAScript. You can only differentiate between instances of built-in classes and normal objects using Object#toString
. They all have the same level of complexity, for instance, whether they are created using {}
or the new
operator.
Object.prototype.toString.call(object)
is your best bet to differentiate between normal objects and instances of other built-in classes, as object === Object(object)
doesn't work here. However, I can't see a reason why you would need to do what you're doing, so perhaps if you share the use case I can offer a little more help.
Solution 2
For simply checking against Object or Array without additional function call (speed).
isArray()
let isArray = function(a) {
return (!!a) && (a.constructor === Array);
};
console.log(isArray( )); // false
console.log(isArray( null)); // false
console.log(isArray( true)); // false
console.log(isArray( 1)); // false
console.log(isArray( 'str')); // false
console.log(isArray( {})); // false
console.log(isArray(new Date)); // false
console.log(isArray( [])); // true
isObject()
let isObject = function(a) {
return (!!a) && (a.constructor === Object);
};
console.log(isObject( )); // false
console.log(isObject( null)); // false
console.log(isObject( true)); // false
console.log(isObject( 1)); // false
console.log(isObject( 'str')); // false
console.log(isObject( [])); // false
console.log(isObject(new Date)); // false
console.log(isObject( {})); // true
Solution 3
If its just about detecting whether or not you're dealing with an Object
, I could think of
Object.getPrototypeOf( obj ) === Object.prototype
However, this would probably fail for non-object primitive values. Actually there is nothing wrong with invoking .toString()
to retreive the [[cclass]] property. You can even create a nice syntax like
var type = Function.prototype.call.bind( Object.prototype.toString );
and then use it like
if( type( obj ) === '[object Object]' ) { }
It might not be the fastest operation but I don't think the performance leak there is too big.
Solution 4
underscore.js is using the following
toString = Object.prototype.toString;
_.isArray = nativeIsArray || function(obj) {
return toString.call(obj) == '[object Array]';
};
_.isObject = function(obj) {
return obj === Object(obj);
};
_.isFunction = function(obj) {
return toString.call(obj) == '[object Function]';
};
Solution 5
Hi I know this topic is old but there is a much better way to differentiate an Array in Node.js from any other Object have a look at the docs.
var util = require('util');
util.isArray([]); // true
util.isArray({}); // false
var obj = {};
typeof obj === "object" // true
![Alex Craft](https://i.stack.imgur.com/pU5YW.jpg?s=256&g=1)
Alex Craft
I'm interested in Finance, Investing and Option Pricing. Building reliable, highly diversified and hedged portfolios. Analysing data, presenting it in a nice visual way. Turning idea into product quickly and efficiently. Tags: Asset Pricing, Kelly Criterion, Monte Carlo Modelling, Stochastic Processes, Mechanical and Statistical Hedging, Tail Hedging, Algorithms and Machine Learning, Trading.
Updated on July 05, 2022Comments
-
Alex Craft almost 2 years
Is there any way to efficiently check if the variable is Object or Array, in NodeJS & V8?
I'm writing a Model for MongoDB and NodeJS, and to traverse the object tree I need to know if the object is simple (Number, String, ...) or composite (Hash, Array).
It seems that V8 has fast built-in
Array.isArray
, but how to check if object is an Object? I mean complex object like hash{}
or instance of class, not something likenew String()
?Usually it may be done as this:
Object.prototype.toString.call(object) == "[object Object]"
or this:
object === Object(object)
But it seems that this operations aren't cheap, maybe there's some more efficient? It's ok if it's not universal and doesn't works on all engines, I need it only to work on V8.