In JavaScript, is undefined actually undefined?

And what happens if we set a value to it?

It should be, but it turns out that “undefined” is a variable. So what happens if we set a value to it? The weird world of JavaScript…

TL;DR undefined is not a restricted keyword so we can name by mistake our variable “undefined” and set a value to it which will cause bugs during a runtime. Use linters to prevent it from happening.

There is a good reason for using void keyword instead of undefined in your if statements and this is because undefined variable actually might be defined. The reason behind it is not a restricted keyword. Undefined is a property of the global object, so it’s a variable in a global scope. Go ahead and type window in your browser console — you will find undefined property inside the window object. So:

window.undefined === undefined; // returns true

What’s a “void” in JavaScript?

In simple words: void in JS is an operator used to return “undefined” value.

void 0 == void(0); //true because void 0 is equal to void(0)

void 1 == void(0); //true

void 0 == undefined; //true

void 0 === undefined; //true

void 1241 === void "everything can go here" //true

The above code shows that the void keyword is the best choice when it comes to checking variables for an undefined value.

Disclaimer: at the beginning of the article I wrote that undefined might be defined. That means in some cases “void 0 === undefined” might return false. We will go back to this issue shortly.

What will happen if I define “undefined”?

In modern browsers (including IE11) which support ECMA-262 5th version from 2009 also known as ES5, such a variable still will be undefined because it’s read-only.

15.1 The Global Object

The unique global object is created before control enters any execution context. Unless otherwise specified, the standard built-in properties of the global object have attributes {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}. [...] 15.1.1.3 undefined The value of undefined is undefined (see 8.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Source: ECMAScript Language Specification

Defining the “undefined” variable using the “var” keyword.

If you are used to using let like me, you will get something different:

Defining the “undefined” variable using the “let” keyword.

We get the “Identifier ‘undefined’ has been declared” because it was defined — inside a window object. But shouldn’t we get an error when we use var anyway? We should! That’s why it’s good to type at the beginning of each .js file:

"use strict";

Strict mode will prevent us from defining undefined:

Way better :)

I want to name my variable “undefined” anyway.

There is a trick. The above rule specified in 15.1.1.3 applies only to global objects. Local scopes are different:

function someFunction() {

let undefined = 10;

console.log(undefined);

} someFunction(); //logs 10

ES6 standard introduced new let and const keywords. Variables declared by var keyword are scoped to the immediate function body (hence the function scope) while let variables are scoped to the immediate enclosing block denoted by { } . Source: What’s the difference between using “let” and “var”? But there is one little downside:

In this example, we can see that strict mode won’t prevent us from setting the undefined variable!

EDIT: There is a reason to set a value to undefined. In a jQuery undefined is specified as a parameter to make sure it wasn’t defined before, for example in other included in project script:

;( function( $, window, document, undefined ) { ... }

undefined isn’t really being passed in so we can ensure the value of it is truly undefined. In ES5, undefined can no longer be modified.

How about Node.js?

Turns out we can set a value to undefined in node.js environment as well. But Node.js Supports ES5 so what‘s going on here?

The answer can be found in official Node.js docs:

In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.

Source: Node.js v13.11.0 Documentation

And this is a huge problem. Now when you are writing your if statements like so:

if (myVariable === undefined) {...}

… you can’t be sure if your variable will be undefined because somebody could have named by mistake, a variable “undefined” tens of lines earlier.

Then how to determine if the variable is undefined?

There are multiple ways to do that:

using null

var something; something == null; // true

something === null; // false

I don’t like this way because null is not null in JavaScript but is an object, and you have to remember to use ==, not === which nowadays is not recommended or typical.

2. typeof

var something; typeof something === 'undefined'; // true

typeof something === undefined; // false

Typeof always returns a string. Back in times when I was a beginner in JavaScript, making my first lines of code it wasn’t obvious for me why I should check for undefined with a string. For this reason, I don’t like doing so but it’s recommended in ESLint so this is an option as well.

3. check if the variable has a value

var something; if(something) console.log("is not undefined");

Although it will work I wouldn’t recommend it, because variable something could be set to false which means it has a value and is not undefined anymore.

4. void 0

var something; void 0 == something; // true

void 0 === something; // true

I think this is the best way. There is not much to remember because void 0 is always undefined. It looks unusual but it does its job and is easy to type.

No-undefined / no-shadow-restricted-names in ESLint

ESLinter comes with no-undefined and no-shadow-restricted-names rules, which enforces us, to not use undefined anywhere. For this reason (and not only) it’s good to use code linters. You can read more about these rules here:

Summary