undefined vs void

void is an operator that evaluates a given expression and then returns undefined.

Difference

In the modern browsers which supports ES5, there's no difference between using the void operator and the undefined value directly:
void 0 === undefined;       // true
void 1 === undefined;       // true
void 'Foo' === undefined;   // true
However, in the old browsers which run ES3 engine, undefined is a global property and can be changed.
// In ES3
console.log(undefined);
var undefined = 'foo';
console.log(undefined);     // 'foo'
On the other hand, it's not possible to override the void operator. Hence, void is used as a replacement for undefined to get the undefined value in a safe way.
In ES5, it's impossible to override undefined because it's set Writeable as false.

Good to know

  1. void is an operator, not a function. So we don't need to wrap the expression in parentheses. void 0 is equivalent to void(0).
  2. There are minifiers which use void 0 to shorten undefined.
  3. If you use immediately-invoked function expression (known as IIFE), void can be used to treat the function keyword as an expression, not a declaration.
    Assume that we want to execute the following IIFE function:
    function run() {
        console.log('Executed');
    }();
    then we can either use void
    void function run() {
        console.log('Executed');
    }();
    or wrap the function in parentheses as below:
    (function run() {
        console.log('Executed');
    })();
  4. void can be used to avoid the side effect when using with arrow functions.
    As we know, ES6 arrow functions allow to use the return value of function by omitting the braces from the function body.
    const sum = (a, b) => a + b;
    In some cases, we don't intend to use the return value of function, because it can lead to a different behavior. Let's say that we are going to handle the click event of a button:
    button.onclick = () => doSomething();
    It works as usual until someone changes doSomething, and makes it return a boolean value. In the case it returns false, the default behavior of the click event will be skipped, and it maybe the thing you don't want to.
    Passing the result to void will ensure that it doesn't change the behavior of arrow function regardless the result of executed functions:
    button.onclick = () => void doSomething();
  5. The advantage of using void with arrow functions can be seen in modern libraries such as React, Svelte.
    These libraries allow us to execute a function right after a component mounted to the DOM. For example, React provides useEffect, Svelte has onMount.
    If we return a function inside the callback, then the function will be invoked to clean up things, free the memory before the component is removed from the screen.
    // React example code
    useEffect(() => doSomething());
    It can produce bugs at run time. To avoid that, we can either use void
    useEffect(() => void doSomething());
    or using the braces:
    useEffect(() => {
        doSomething();
    });

Good practice

The void operator has been used in the URL prefixed with javascript:.
By default, the browser will evaluate the code when following a javascript: URI, and then replaces the contents of page with the returned value.
To prevent the default behavior, the code must return undefined. That's why we have been seeing the following code:
<a href="javascript: void(0);" onclick="doSomething">
    ...
</a>
Nowadays, using javascript: protocol isn't recommended. It can create a security issue since user can put unsanitized input in the event handler:
<a href="javascript: alert('unsanitized input')">
    ...
</a>
Starting from v16.9.0, React also deprecates the usage of javascript: URLs.

More

Hit the Subscribe button for the latest news on my tools. No spam. Ever!
© 2020 Nguyen Huu Phuoc. All rights reserved