difference between "void 0 " and "undefined"

26,735

Solution 1

From MDN:

The void operator evaluates the given expression and then returns undefined.

This operator allows inserting expressions that produce side effects into places where an expression that evaluates to undefined is desired.

The void operator is often used merely to obtain the undefined primitive value, usually using "void(0)" (which is equivalent to "void 0"). In these cases, the global variable undefined can be used instead (assuming it has not been assigned to a non-default value).

Closure Compiler swaps in void 0 because it contains fewer characters than undefined, therefore producing equivalent, smaller code.


Re: OP comment

yes, I read the documentation, but in the example I gave, "google closure" in a case using "void 0" and another "undefined"

I believe this is actually a bug in Google Closure Compiler!

Solution 2

The real only semantic difference between void expr and undefined is that on ECMAScript 3, the undefined property of the global object (window.undefined on browser environments) is writable, whereas the void operator will return the undefined value always.

A popular pattern that is often implemented, to use undefined without worries is simply declaring an argument, and not passing anything to it:

(function (undefined) {
  //...
  if (foo !== undefined) {
    // ...
  }

})();

That will allow minifiers to shrink the argument maybe to a single letter (even shorter than void 0 :), e.g.:

(function (a) {
  //...
  if (foo !== a) {
    // ...
  }
})();

Solution 3

Just a follow-up on all the answers before.

They look the same, but to the Compiler they are completely different.

The two code sections compile to different outputs because one is referring to a local variable (the var undefined), and the compiler simply in-lines it because it is used exactly once and is no more than one line. If it is used more than once, then this in-lining won't happen. The in-lining provides a result of "undefined", which is shorter to represent as "void 0".

The one without a local variable is referring to the variable called "undefined" under the global object, which is automatically "extern'ed" by the Closure Compiler (in fact, all global object properties are). Therefore, no renaming takes place, and no in-lining takes place. Voila! still "undefined".

Solution 4

There is no difference, Try it yourself:

void 0 === undefined

will evaluate to true.
undefined is 3 characters longer, I guess that is the reason why they use it that way.

Share:
26,735
andres descalzo
Author by

andres descalzo

I'm a developer of web and desktop applications, interested in the following technologies and languages​​: .NET C# Framework and Core Javascript ASP.NET Framework and Core

Updated on July 08, 2022

Comments

  • andres descalzo
    andres descalzo almost 2 years

    I'm using "Closure Compiler", when compiling my scripts I spend the following:

    Before compiling:

    // ==ClosureCompiler==
    // @compilation_level SIMPLE_OPTIMIZATIONS
    // @output_file_name default.js
    // @formatting pretty_print,print_input_delimiter
    // ==/ClosureCompiler==
    
    var myObj1 = (function() {
    
      var undefined;   //<----- declare undefined
    
      this.test = function(value, arg1) {
    
        var exp = 0;
        arg1 = arg1 == undefined ? true : arg1;  //<----- use declare undefined
        exp = (arg1) ? value * 5 :  value * 10;
    
        return exp;
      };
    
      return this;
    }).call({});
    
    var myObj2 = (function() {
    
      this.test = function(value, arg1) {
    
        var exp = 0;
        arg1 = arg1 == undefined ? true : arg1;  //<----- without declare undefined
        exp = (arg1) ? value * 5 :  value * 10;
    
        return exp;
      };
    
      return this;
    }).call({});
    

    Compiled:

    // Input 0
    var myObj1 = function() {
      this.test = function(b, a) {
        a = a == void 0 ? true : a;  //<-----
        var c = 0;
        return c = a ? b * 5 : b * 10
      };
      return this
    }.call({}), myObj2 = function() {
      this.test = function(b, a) {
        a = a == undefined ? true : a; //<-----
        var c = 0;
        return c = a ? b * 5 : b * 10
      };
      return this
    }.call({});
    

    With this I believe the question of the use of "void 0 " and "undefined", is there any difference in the use or the two cases are well?.

    Edit

    if I define "var undefined" compiled with "void 0 ", if I did not define "undefined" compiled with "undedined. " then not a matter of number of characters between "undefined" and "void 0"

    Test

    Edit II: performance, based on this link

    Code and Test

    IE 8:
    typeof: 228ms
    undefined: 62ms
    void 0: 57ms

    Firefox 3.6:
    typeof: 10ms
    undefined: 3ms
    void 0: 3ms

    Opera 11:
    typeof: 67ms
    undefined: 19ms
    void 0: 20ms

    Chrome 8:
    typeof: 3ms
    undefined: 5ms
    void 0: 3ms

  • Joel Coehoorn
    Joel Coehoorn over 13 years
    And therefore it's a bandwidth optimization: send fewer bytes over the wire?
  • jAndy
    jAndy over 13 years
    @JoelCoehoorn: well the closure compiler is a minifier aswell, I guess they try to squeeze every byte here.
  • andres descalzo
    andres descalzo over 13 years
    if I define "var undefined" compiled with "void 0 ", if I did not define "undefined" compiled with "undedined". then not a matter of number of characters between "undefined" and "void 0"
  • jAndy
    jAndy over 13 years
    Nice. Thanks for that, I was wondering whether the undefined value is a property or not. typeofnan.blogspot.com/2011/01/typeof-is-fast.html
  • andres descalzo
    andres descalzo over 13 years
    yes, I read the documentation, but in the example I gave, "google closure" in a case using "void 0" and another "undefined"
  • Christian C. Salvadó
    Christian C. Salvadó over 13 years
    @jAndy, Nice article, and thanks for the mention ;), BTW you could add a test against void 0, it might be interesting...
  • andres descalzo
    andres descalzo over 13 years
    see the article @jAndy, is very interesting. typeofnan.blogspot.com/2011/01/typeof-is-fast.html
  • jAndy
    jAndy over 13 years
    Thanks! I insta checked that, void 0 performs way better than undefined obviously now, but it's still behind the cached version.
  • Aidiakapi
    Aidiakapi about 10 years
    I think if you use this method on any non-anonymous and not immediately called functions you'll be asking for trouble. If somebody calls it with the parameter (in most cases passing extra parameters to a function doesn't influence behavior, such as alert('test', '2nd param ignored')) for example through code like someFunc.apply(this, arguments) you risk comparing against a completely different variable. I wouldn't rely on this technique to save a mere 5 characters that'll most likely be even less when GZIPed.
  • Alexander Suraphel
    Alexander Suraphel about 9 years
    CMS, but window.undefined = 0 but assert( 0 != undefined). Am I missing something.
  • huysentruitw
    huysentruitw almost 9 years
    Stay away from this! You can't see if you're passing a variable to undefined or not because the actual call can be 100's of lines away. While foo !== undefined will probably still work when you're passing in an other value for undefined, tests like foo === undefined will open pandora's box.
  • Harry
    Harry over 7 years
    (function () { return 'foo' })() === 'foo' also returns true. DOES THAT MEAN THERE IS NO DIFFERENCE BETWEEN THE TWO?
  • FrancescoMM
    FrancescoMM almost 7 years
    @Harry, in the code there is a huge difference. But after evaluation, both sides are actually "foo" strings. Undefined is the result of void. So, even if void 0, in the code, is not the same as undefined, it really evaluates to undefined, it is undefined after evaluation. In the same way we say "2+2 is 4". Yes, "2+2" is NOT 4, it evaluates to 4, but after evaluation it IS 4!
  • Steve Bennett
    Steve Bennett over 4 years
    There's no difference if undefined has not been redefined. That's not always a safe assumption.
  • PuiMan Cheui
    PuiMan Cheui over 3 years
    [][0] is another alternative