2011-05-26

The void operator in JavaScript

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 you 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. You 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

void 0 and void(0) are the same as undefined, with one exception: undefined can be shadowed or redefined:
    > function a(undefined) { return undefined; }
    > a("hello")
    ’hello’

    > undefined = "foo";
    > console.log(undefined);
    foo
In contrast, void cannot change its meaning (the arrow always points behind the offending token):
    > function b() { var void = function() {}; return void(0); }
    missing variable name
    function b() { var void = function() {}; return void(0); }
    .......................^
    
    > void = "foo";
    syntax error
    void = "foo";
    ......^
In case you were wondering: strict mode does not prevent the value of undefined from being changed.

Best practice. If you are paranoid about shadowing or globally changing undefined, use void 0. Otherwise, use the more descriptive undefined; not everyone reading your code might be familiar with the void operator.

Use case: bookmarklets

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.

Use case: links that execute JavaScript code

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, you 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>

17 comments:

Chris Marisic said...

Now that's just spiffy.

Will said...

So now I understand what the void operator does, but I still have no idea what it's useful for. I can't think of a single use case. Neither of the examples above make any sense at all to me. "javascript:void(3+4)" -- okay, so it evalutates 3+4 and returns undefined. But what has that accomplished? Senseless use of a few processor cycles? Same with 'javascript:void window.open("http://www.whitehouse.gov/")' -- I mean, if it doesn't replace the contents of the window, then what has it done? Couldn't you "not open a window" even faster by simply executing no command?

Axel Rauschmayer said...

Good question, thanks. The use cases were more or less implied. I’ve edited the content to make it clear what they actually are.

Note: void window.open(...) is not about "not opening a window"! Try both URLs by entering them into your web browser while you are on a website, then you’ll see the difference. In either case, a new window/tab is opened, but only with void does the old window remain unchanged.

Wolfram said...

funny, javascript:void what I used years ago and now you give it some sense :)

Scott Hanson said...

Note that you'll need to be in a non-Webkit browser for you to see the difference between the two. There's no difference between the two in Safari (5.0.5) and Chrome (11) (at least on a Mac).

Axel Rauschmayer said...

Interesting, I hadn’t tested this on those browsers (only on Firefox). Seems like a shame, because then performing quick calculations via javascript: URLs becomes harder.

JustinJohnson.org said...

A shorter and always correct version of` myVoid` would be simply

myVoid = function() {};

There is no reason to return anything if you just want the undefined value. Your version can be broken by defining `undefined` globally.

Also, when you say, "The operator binds very closely," it might be clearer if you talk about its precedence. The `void` operator has a precedence of 4, similar to `delete` and `typeof` (https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence).

Interesting article; though, I think the only modern use is for bookmarklets.

Axel Rauschmayer said...

Your myVoid: is the more concise of the two versions, but I didn’t aim for conciseness, I wanted to illustrate, how the operator throws away its argument and returns something different.

Operator precedence: agreed! I’ve changed the post slightly.

JavaScriptBank.com said...

cool js code & tips, thank for sharing

Jaypee said...

Hello Everyone,
We can use arithmetic operators in java script to perform mathematical
calculation or used to solve mathematical expression........
for more details please check out this link...http://mindstick.com/Articles/6e9196a6-3d72-468c-898f-91f5632da53b/?Implementing%20%20Operators%20in%20Java%20Script

Thanks !!!!!

trev.norris said...

one small thing about your void function. It doesn't evaluate the passed expression. Shouldn't it be a bit more like this:

function void( expr ) {
    return eval( expr );
}

Axel Rauschmayer said...

This would be a problem in a programming language with lazy evaluation (such as Haskell). In JavaScript, all arguments are evaluated before invoking a function. Careful with eval(): it might not do what you think it does, it interprets/evaluates a string.

Jonathan Buchanan said...

Another use case: turning a function declaration into a function expression so it can be called immediately, as an alternative to ()() wrapping (neatly avoiding ASI issues if you don't use semicolons) or using other operators such as ! to turn it into an expression (a wee bit esoteric, personally I feel void expresses intent better).

void function() { /* ... */ }()

Axel Rauschmayer said...

 Clever. Great for people who miss Java. ;-)

Thankfully, ES.next will give us block scoping, so IIFEs will go away, in the long run.

Dave said...

not really, you would just use
javascript:void window.alert(3+5);

Java Training In Chennai said...

The normal way to get the undefined value for comparison is void.


For instance: javascript:alert(undefined === void 0).

Axel Rauschmayer said...

You have two choices: undefined or void (see the article for how they are different). If one of the two was to be called “normal”, it would be the former. But, if you want to avoid the risk of redefinition (which doesn’t matter very often) then you need to use void.

Web Analytics