“void 0”和“undefined”之间的区别

时间:2011-01-26 15:24:22

标签: javascript google-closure google-closure-compiler

我正在使用"Closure Compiler",在编译脚本时我会花费以下内容:

编译前:

// ==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({});

编译:

// 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({});

有了这个我相信使用“void 0”和“undefined”的问题,使用上有什么不同或两种情况都很好吗?

修改

如果我定义用“void 0”编译的“var undefined”,如果我没有定义用“undedined”编译的“undefined”,那么不是“undefined”和“void 0”之间的字符数问题

Test

编辑II:效果,基于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

4 个答案:

答案 0 :(得分:65)

From MDN

  

void运算符会评估给定的 expression ,然后返回undefined

     

此运算符允许将产生副作用的表达式插入到需要求值为undefined的表达式的位置。

     

void运算符通常仅用于获取undefined原始值,通常使用“void(0)”(相当于“void 0”)。在这些情况下,可以使用全局变量undefined(假设它尚未分配给非默认值)。

Closure编译器在void 0中交换,因为它包含的字符数少于undefined因此生成等效的小代码


Re:OP评论

  

是的,我阅读了文档,但在我给出的示例中,“google closure”在使用“void 0”和另一个“undefined”

的案例中

我相信这实际上是bug in Google Closure Compiler

答案 1 :(得分:52)

void exprundefined之间真正唯一的语义差异在于 ECMAScript 3 ,即全局对象的undefined属性(window.undefined在浏览器环境中)是可写的,而void运算符将返回undefined始终

经常实现的流行模式,使用undefined而不用担心只是声明一个参数,而不是传递任何东西:

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

})();

这将允许minifiers将参数缩小为单个字母(甚至短于void 0 :),例如:

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

答案 2 :(得分:8)

以前对所有答案的跟进。

它们看起来一样,但对于编译器来说,它们完全不同。

这两个代码段编译为不同的输出,因为一个是指一个局部变量(var undefined),编译器只是内联它,因为它只使用了一次而且不超过一行。如果不止一次使用,则不会发生这种内衬。内嵌提供了“未定义”的结果,它更短,表示为“void 0”。

没有局部变量的那个是指全局对象下的名为“undefined”的变量,它由Closure Compiler自动“extern”化(实际上,所有全局对象属性)是)。因此,不进行重命名,也不会发生内衬。瞧!仍然“未定义”。

答案 3 :(得分:4)

没有区别,请亲自尝试:

void 0 === undefined

将评估为true undefined 3 个字符更长,我想这就是他们以这种方式使用它的原因。