Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

typeof object but not array

I am looking for a quick check to determine if a value is an object {} but not an array []. I have written this:

function isPlainObject(input) {
   return !Array.isArray(input) && typeof input === 'object';
}

Is there a shorter check I can use to determine this?

Or are there other possible data structures that still checkout as typeof 'object'?

like image 966
Alexander Mills Avatar asked Dec 24 '16 06:12

Alexander Mills


People also ask

How do you check if an object is not an array?

Example: Check Array Using Array. isArray() method is used to check if an object is an array. The Array. isArray() method returns true if an object is an array, otherwise returns false . Note: For an array, the typeof operator returns an object.

Is an array typeof object?

One type of object that is built-in to JavaScript is the array, and the typeof of an array is "object" : typeof [] === `object` // true . ECMAScript 5 introduced an Array. isArray() method to check for an array, since typeof will not be able to tell arrays from other objects.

Why in JS typeof array is object?

Apparently there seems to be something wrong because the array is recognized as an object and seems to be no real difference between object and array. This because in javascript all derived data type is always a type object.

How do you check if an object is an array or not in JavaScript?

The isArray() method returns true if an object is an array, otherwise false .


2 Answers

It is not quicker, but more precise, with a check for falsy values, like null, which is an object.

function isPlainObject(input) {
   return input && !Array.isArray(input) && typeof input === 'object';
}
like image 57
Nina Scholz Avatar answered Sep 22 '22 03:09

Nina Scholz


If you want to check if an object is a "plain" object, i.e. inherits directly from Object.prototype, then you should check for that.

E.g. the following first tests if value has Object anywhere on it's prototype chain (and hence will not throw an error for getPrototypeOf), then checks if its immediate [[prototype]] is Object.prototype:

function isPlainObject(value) {
  return value instanceof Object &&
         Object.getPrototypeOf(value) == Object.prototype;
}

// Some tests
[[1,2],         // Array
 {},            // Plain object
 null,          // null
 document.createElement('div'),  // host object
 function(){},  // function object
 console        // host objet
 ].forEach(function(value) {
      console.log(value + ': ' + isPlainObject(value));
 });

Edit

If you want to test that the input is some extended object but not a Function, etc. that is much less efficient, e.g. test against some list of objects that you want to avoid:

function isJustObj(obj) {
  var notThese = [Function, Array, Date];
  if (obj instanceof Object) {
    return !notThese.some(function(o) {
      return obj instanceof o;
    });
  }
  return false;
}

function Foo(){}

var tests = {'Array: ':[],
             'Object: ' : {},
             'Foo instance:' : new Foo(),
             'Function: ' : function(){},
             'Date: ' : new Date(),
             'Host obj: ' : document.createElement('div')
};

Object.keys(tests).forEach(function(test) {
  console.log(test + isJustObj(tests[test]));
})

Note that this strategy sees if the value is some kind of Object, then tests whether it's an instance of a particular set of constructors. This list of things to exclude can become very large since it's not possible in any reasonable way to rule out host objects which, by their very nature, can be indistinguishable from built-in objects based on some general test (see Is there an environment-agnostic way to detect Javascript Host Objects?).

E.g.

console.log instanceof Function // true
console instanceof Object       // true
isPlainObject(console)          // false

So you either check if Object.prototype is the immediate [[Prototype]] or create a long list of constructors to test against. That list will go out of date very quickly given the variety of host environments available and the freedom for implementors to extend it. Also, you need to test every member of the host object set before trying to use it as it may not exist for the particular host on which the code is running.

like image 39
RobG Avatar answered Sep 21 '22 03:09

RobG