The void operator in JavaScript

[2011-05-26] dev, javascript, jslang
(Ad, please don’t block)

Update 2022-09-12: I updated the content to reflect the status quo.


Syntax.

void <expr>

evaluates expr and returns undefined.

Examples:

> void 0
undefined
> void(0)
undefined

> void 4+7  // same as (void 4)+7
NaN
> void(4+7)
undefined

> var x;
> x = 3;
3
> void(x = 5);
undefined
> x
5

Thus, if we could manually implement void as a function, it would look as follows:

function void(expr) { // not possible: syntax error!
  return undefined;
}

Operator precedence. The operator is associated closely with its operand. We should therefore put parentheses around its operand if it contains more than a single token. For example, void 4+7 binds as (void 4)+7.

Three use cases for void. The following subsections describe three use cases for the void operator:

  1. Use case: void 0 as undefined
  2. Use case: bookmarklets
  3. Use case: links that execute JavaScript code

Use case: void 0 as undefined  

As expressions, void 0, void(0), and undefined are mostly equivalent, but there is one major difference:

  • void is a keyword and can’t be used as a variable name. That means that we can’t change its definition either:

    > eval('const void = 123')
    Uncaught SyntaxError: Unexpected token 'void'
    
  • undefined is a normal variable name. We can’t change its value but we can shadow it – as we’ll see soon.

undefined is a property of the global object:

> Object.getOwnPropertyDescriptor(globalThis, 'undefined')
{
  value: undefined,
  writable: false,
  enumerable: false,
  configurable: false
}

For more information on property attributes and property descriptors, see “JavaScript for impatient programmers”.

Because property .undefined is neither writable nor configurable, we can’t change its value. This is what happens in strict mode (in non-strict mode, the assignment will fail silently):

assert.throws(
  () => {
    undefined = 123
  },
  /^TypeError: Cannot assign to read only property 'undefined'/
);

We can, however, shadow its original value via a variable declaration:

{
  const undefined = 123;
  assert.equal(
    undefined, 123
  );
}

Or via a parameter:

function myFunc(undefined) {
  assert.equal(undefined, 'hello');
}
myfunc('hello');

Thoughts:

  • Before ECMAScript 5, it was possible to redefine the global property .undefined and void was useful as a “safer undefined”. However that’s not an issue anymore.

  • Shadowing undefined should never be a problem because we control shadowing in our own code.

  • Therefore, we can safely use the more self-descriptive undefined and don’t need void as an alternative.

Use case: bookmarklets  

Warning: outdated information

Bookmarklets are URLs with JavaScript programs that are "executed in the address bar". If a bookmarklet returns a result that is not undefined, the content of the currently shown web page is replaced with it. It is such a perfect use case for the void operator. Compare [This difference only exists on non-Webkit browsers. E.g., Safari and Chrome don't exhibit it, Firefox does.]:

  • javascript:3+4 displays 7 as the current document.
  • javascript:void(3+4) does not change the current document. void "hides" the result of the expression 3+4.

Similarly:

  • javascript:window.open("http://www.whitehouse.gov/") replaces the content of the current page.
  • javascript:void window.open("http://www.whitehouse.gov/") does not change the content of the current page.

A more involved example: The following bookmarklet lets one submit the URL of the current web page to the site submit.example.com:

javascript:void window.open(
"http://submit.example.com/submit?"+
encodeURIComponent(document.location.href)
)

This bookmarklet does not change the current page and displays the confirmation of a successful submission in a new window/tab.

Warning: outdated information

A discouraged, but possible, use case is to embed a link in a webapp that invokes a JavaScript function. If the function returns void (which also happens if it does not have a return statement at all), then everything is OK. On the other hand, if the function that is called returns a value, we need to prevent the page content from being changed, via the void operator. (This difference only exists on non-Webkit browsers. E.g., Safari and Chrome don't exhibit it, Firefox does.) In the following example, function computeResult() returns a number.

<a href="javascript:void computeResult()">Compute</a>