"void 0"和"undefined"之间的区别

and*_*lzo 59 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({});
Run Code Online (Sandbox Code Playgroud)

编译:

// 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({});
Run Code Online (Sandbox Code Playgroud)

有了这个我相信使用"void 0"和"undefined"的问题,在使用上有什么不同或两个案例都很好吗?

编辑

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

测试

编辑II:性能,基于此链接

代码和测试

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

Mat*_*all 67

来自MDN:

void运算符计算给定的expression,然后返回undefined.

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

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

Closure Compiler交换,void 0因为它包含的字符数少于undefined,因此生成相同的较小代码.


回复:OP评论

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

我相信这实际上是Google Closure Compiler中的一个错误!

  • 看到文章@jAndy,非常有趣.http://typeofnan.blogspot.com/2011/01/typeof-is-fast.html (2认同)

CMS*_*CMS 53

之间的真正唯一的语义差别void expr,并undefined是对的ECMAScript 3中,undefined全局对象(财产window.undefined上的浏览器环境)是可写的,而void 运营商将返回undefined始终.

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

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

})();
Run Code Online (Sandbox Code Playgroud)

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

(function (a) {
  //...
  if (foo !== a) {
    // ...
  }
})();
Run Code Online (Sandbox Code Playgroud)


Ste*_*ung 8

只是对之前所有答案的后续跟进.

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

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

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


jAn*_*ndy 5

没有什么区别,自己尝试一下:

void 0 === undefined
Run Code Online (Sandbox Code Playgroud)

将评估为true.
undefined长了3 个字符,我想这就是他们这样使用它的原因。

  • 因此,这是一种带宽优化:通过线路发送更少的字节? (2认同)
  • `(function () { return 'foo' })() === 'foo'` 也返回 true。这是否意味着两者之间没有区别? (2认同)
  • @Harry,代码中存在巨大差异。但求值后发现两边其实都是“foo”字符串。未定义是 void 的结果。所以,即使代码中的 void 0 与 undefined 不一样,它确实评估为 undefined,评估后它是 undefined。同样的道理,我们说“2+2等于4”。是的,“2+2”不是 4,它的计算结果是 4,但计算后它是 4! (2认同)