web-dev-qa-db-ja.com

「void 0」と「undefined」の違い

私は "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」の使用の問題は、使用に違いはありますか、それとも2つのケースは問題ないでしょうか。

編集

「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

オペラ11:
typeof:67ms
undefined:19ms
void 0:20ms

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

59
andres descalzo

MDNから

void演算子は、指定されたexpressionを評価して、undefinedを返します。

この演算子を使用すると、未定義と評価される式が必要な場所に副作用を引き起こす式を挿入できます。

Void演算子は、通常undefinedプリミティブ値を取得するためにのみ使用されることが多く、通常は「void(0)」(「void 0」と同等)を使用します。これらの場合、代わりにグローバル変数undefinedを使用できます(デフォルト以外の値に割り当てられていない場合)。

クロージャーコンパイラは、undefinedよりも少ない文字数を含むため、void 0にスワップします。、したがって同等の小さなコードを生成します


日時:OPコメント

はい、私はドキュメントを読みましたが、私が与えた例では、「void 0」と別の「undefined」を使用する場合の「google closure」

これは実際には Google Closure Compilerのバグ

67
Matt Ball

void exprundefinedの真の意味上の違いは、ECMAScript、グローバルオブジェクトのundefinedプロパティ(window.undefined onブラウザ環境)は書き込み可能ですが、void演算子はundefined値を返しますalways

undefinedを心配なく使用するために実装されることが多い人気のあるパターンは、単に引数を宣言し、引数を何も渡さないことです。

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

})();

これにより、ミニファイヤは引数をおそらく1文字(void 0:よりも短い)に縮小できます。例:

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

以前のすべての回答のフォローアップです。

これらは同じように見えますが、コンパイラにとってはまったく異なります。

1つはローカル変数(var undefined)を参照しているため、2つのコードセクションは異なる出力にコンパイルされます。コンパイラーは1回だけ使用され、1行以下であるため、単純にインライン化します。複数回使用される場合、このインライン化は行われません。インラインは、「undefined」の結果を提供しますが、これは「void 0」として表すためにより短くなります。

ローカル変数のないものは、global objectの下にある「undefined」と呼ばれる変数を参照します。これは、Closure Compilerによって自動的に「extern」されます(実際、すべてのグローバルオブジェクトプロパティは)。したがって、名前の変更は行われず、インライン化も行われません。出来上がり!まだ「未定義」です。

8
Stephen Chung

違いはありません、自分で試してください:

void 0 === undefined

trueと評価されます。
undefinedは文字長です。これが彼らがそのように使用する理由です。

4
jAndy