web-dev-qa-db-ja.com

babelがインポートされた関数呼び出しを(0、fn)(...)に書き換えるのはなぜですか?

次のような入力ファイルが与えられた場合

_import { a } from 'b';

function x () {
  a()
}
_

babelはそれをコンパイルします

_'use strict';

var _b = require('b');

function x() {
  (0, _b.a)();
}
_

ただし、ルーズモードでコンパイルすると、関数呼び出しは_b.a();として出力されます

私はそれを説明するコメントがあったことを期待して、コンマ演算子がどこに追加されるかについていくつかの研究をしました。追加するコードは here です。

92
Will Smith

_(0, _b.a)()_は、関数オブジェクト__b.a_がthisがグローバルオブジェクトに設定された状態で呼び出されることを保証します(または厳格モードが有効な場合、undefinedに設定されます)。 _b.a()を直接呼び出す場合、thisを__b.a_に設定して__b_が呼び出されます。

_(0, _b.a)();_は次と同等です

_0; // Ignore result
var tmp = _b.a;
tmp();
_

(_,_はコンマ演算子です。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator を参照してください)。

129
Rob W

コンマ演算子は、各オペランドを(左から右に)評価し、最後のオペランドの値を返します。

console.log((1, 2)); // Returns 2 in console
console.log((a = b = 3, c = 4)); // Returns 4 in console

例を見てみましょう:

var a = {
  foo: function() {
    console.log(this === window);
  }
};

a.foo(); // Returns 'false' in console
(0, a.foo)(); // Returns 'true' in console

これで、fooメソッドでは、thisaと等しくなります(fooaに付加されるため)。したがって、a.foo()を直接呼び出すと、コンソールにfalseが記録されます。

ただし、(0, a.foo)()を呼び出した場合。式(0, a.foo)は、各オペランドを(左から右に)評価し、最後のオペランドの値を返します。つまり、(0, a.foo)は次と同等です。

function() {
  console.log(this === window);
}

この関数はもはや何にも接続されていないため、そのthisはグローバルオブジェクトwindowです。そのため、(0, a.foo)()を呼び出すと、コンソールにtrueが記録されます。

20
Huong Hk