【问题标题】:difference between "void 0 " and "undefined"“void 0”和“undefined”之间的区别
【发布时间】:2011-01-26 15:24:21
【问题描述】:

我正在使用"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

编辑二:性能,基于this link

Code and Test

IE 8:
类型:228 毫秒
未定义:62ms
无效 0:57 毫秒

Firefox 3.6:
类型:10ms
未定义:3ms
无效 0:3 毫秒

Opera 11:
类型:67 毫秒
未定义:19 毫秒
无效 0:20 毫秒

Chrome 8:
类型:3ms
未定义:5ms
无效 0:3 毫秒

【问题讨论】:

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


    【解决方案1】:

    From MDN:

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

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

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

    Closure Compiler 换入 void 0,因为它包含的字符比 undefined 少,因此产生等效的、更小的代码


    回复:OP 评论

    是的,我阅读了文档,但在我给出的示例中,“谷歌关闭”在使用“void 0”和另一个“未定义”的情况下

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

    【讨论】:

    • 是的,我阅读了文档,但在我给出的示例中,在使用“void 0”和另一个“未定义”的情况下,“google 关闭”
    • 看文章@jAndy,很有意思。 typeofnan.blogspot.com/2011/01/typeof-is-fast.html
    • [][0] 是另一种选择
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 不错。谢谢你,我想知道undefined 值是否是一个属性。 typeofnan.blogspot.com/2011/01/typeof-is-fast.html
    • @jAndy,不错的文章,感谢您的提及;),顺便说一句,您可以添加针对 void 0 的测试,这可能会很有趣...
    • 谢谢!我检查了一下,void 0 现在的性能显然比undefined 好得多,但它仍然落后于缓存版本。
    • 我认为,如果您在任何非匿名且未立即调用的函数上使用此方法,您将自找麻烦。如果有人使用参数调用它(在大多数情况下,将额外参数传递给函数不会影响行为,例如alert('test', '2nd param ignored')),例如通过someFunc.apply(this, arguments) 之类的代码,您就有可能与完全不同的变量进行比较。我不会依靠这种技术来保存仅 5 个字符,当 GZIPed 时很可能会更少。
    • CMS,但window.undefined = 0assert( 0 != undefined)。我错过了什么吗?
    【解决方案3】:

    只是对之前所有答案的跟进。

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

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

    没有局部变量的指的是全局对象下名为“undefined”的变量,它被闭包编译器自动“extern'ed”(实际上是所有全局对象的属性)是)。因此,不会发生重命名,也不会发生内联。瞧!仍然“未定义”。

    【讨论】:

      【解决方案4】:

      没区别,自己试试吧:

      void 0 === undefined
      

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

      【讨论】:

      • 因此这是一种带宽优化:通过网络发送更少的字节?
      • @JoelCoehoorn:闭包编译器也是一个压缩器,我猜他们试图压缩这里的每个字节。
      • 如果我定义了用“void 0”编译的“var undefined”,如果我没有定义用“undedined”编译的“undefined”。那么“undefined”和“void 0”之间的字符数就不是问题了
      • (function () { return 'foo' })() === 'foo' 也返回 true。这是否意味着两者之间没有区别?
      • @Harry,在代码中存在巨大差异。但是经过评估,双方实际上都是“foo”字符串。未定义是 void 的结果。因此,即使代码中的 void 0 与 undefined 不同,它的计算结果确实为 undefined,计算后它是 undefined。同理,我们说“2+2 是 4”。是的,“2+2”不是 4,它的计算结果为 4,但计算后它是 4!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 2015-04-30
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-17
      相关资源
      最近更新 更多