Check if a variable is a JavaScript object
By: Olivier Picault
Tags: Tech, Coding, JavaScript, Programming, Web Development

Check if a variable is a JavaScript object

And nothing else (not an Array, Set, etc.)

I’m currently working on a project where we store certain values as either a string or an object. Depending on the type of the value, we will handle it in a different way. Even though here we expect to only work with a string or an object, I want to write a robust and general function that will determine explicitly if a value is a plain JavaScript object. I want to handle edge cases where other data structures based on JavaScript objects (such as arrays, sets, null, etc) will return false since they are not just a plain object.

After some digging, I found multiple possible answers and did some TDD to pick the right one because I wanted to be sure all the cases I could think of were covered. I will write and test an isObject function.

Project setup

We don’t need crazy fancy stuff here. A folder with two files is enough:

isObject.js

isObject.test.js

mkdir isObject && cd isObject

touch isObject.js && touch isObject.test.js

We’ll also need a testing library (and the Babel support to write modern JS).

I’ll be using Jest as it’s easy to set up and use.

yarn init

yarn add jest -D

yarn add --dev babel-jest @babel/core @babel/preset-env

Finally a babel.config.js file.

module.exports = {

presets: [

[

'@babel/preset-env',

{

targets: {

node: 'current',

},

},

],

],

};

You can find all of this Jest setup in the Jest official documentation.

TDD Basics

Let’s write a dummy function for now

Now the test. We want our function to be able to test any value without performing any pre-checks.

We are a testing for string and object types which are the cases we will definitely encounter the most but also for others to make sure our function is working with edge cases.

Run the test suite:

jest isObject.test.js

It should fail.

Solutions

Let’s implement our isObject function now.

typeof

The first solution I thought of was to use typeof

Run the test.

jest isObject.test.js

It fails.

FAIL ./isObject.test.js

isObject

✓ String (3ms)

✓ Object (1ms)

✕ Array (6ms)

✕ Set

✕ Date (1ms)

✓ Undefined

✕ Null

The problem with typeof is that typeof [] === 'object' is actually true . Why? Because in Javascript arrays are actually objects. The same goes for Set, Date, etc.

Interesting things to notice:

typeof undefined is not object . It’s undefined .

is not . It’s . typeof null is an object though.

instanceof

and the results:

FAIL ./isObject.test.js

isObject

✓ String (3ms)

✓ Object (1ms)

✕ Array (2ms)

✕ Set

✕ Date (1ms)

✓ Undefined

✓ Null

This is a little bit better ( null and undefied are treated the same way) but still fails for some of our cases. Why ? Because instanceof checks if the specified prototype (here Object ) appears anywhere in the prototype chain.

As said above array are actually object in JavaScript so:

[] instanceof Array // true

[] instanceof Object // true

Interesting thing to notice:

null is an object type but not an instance of object

constructor

It fails. Again.

FAIL ./isObject.test.js

isObject

✓ String (3ms)

✓ Object (1ms)

✓ Array

✓ Set

✓ Date

✕ Undefined (1ms)

✕ Null

Almost there! This time it’s because undefined and null don’t have a constructor property but it works for all the other types. We could thus think of something like:

This does the job but it forces us to check for particular values which is something I wanted avoid. I didn’t want to guess the type of a variable by eliminating all the other possibilities.

After some research, I found what I needed.

Object.prototype.toString.call()

PASS ./isObject.test.js

isObject

✓ String (3ms)

✓ Object

✓ Array (1ms)

✓ Set

✓ Date

✓ Undefined

✓ Null

Exactly what I needed.

The toString() method returns a string representing the object. For example here what it returns for an array :

Object.prototype.toString.call([]) // [object Array]

This way I’m sure I’m dealing with an object and nothing else!

A note from JavaScript In Plain English

We have launched three new publications! Show some love for our new publications by following them: AI in Plain English, UX in Plain English, Python in Plain English — thank you and keep learning!

We are also always interested in helping to promote quality content. If you have an article that you would like to submit to any of our publications, send us an email at submissions@plainenglish.io with your Medium username and we will get you added as a writer. Also let us know which publication/s you want to be added to.