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


100

次のような入力ファイルがあるとします

import { a } from 'b';

function x () {
  a()
}

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

'use strict';

var _b = require('b');

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

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

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


4
彼らは_b.a.call()意図を明確にするためにやるべきだった。
ベルギ2015

@Bergi(0、)が付いている理由は、変換されたコードのスペースを節約するためです。
アンディ


回答:


138

(0, _b.a)()関数_b.athisグローバルオブジェクトに設定された状態で呼び出されるようにします(または、厳密モードが有効になっている場合は、にundefined)。_b.a()直接呼び出す場合_b.aは、にthis設定して呼び出され_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を参照してください)。


3
リンクをありがとう。これを何度も通過し、最終的に何が起こっているのかを知ることにしました。
theflowersoftime 2016年

@RobW var _a = (0, _b.a)ファイルの先頭に追加してから呼び出す_aと、多くの場合、より多くのスペースを節約できると思います。
アンディ

1
@Andyあなたの提案には副作用_b.aがあります。
Rob W

@RobWなるほど、そのため、関数を呼び出す必要があるまで、潜在的な副作用を回避することをお勧めします。
アンディ

モジュールは常に厳密なコードであるため、常にそうでthis === undefinedあり、グローバルオブジェクトについて言及する必要さえありません
Bergi

22

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

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メソッドでthisは、はa(にfoo接続されているためa)に等しいです。したがって、a.foo()を直接呼び出すとfalse、コンソールにログインします。

しかし、あなたが呼ばれたら(0, a.foo)()。式(0, a.foo)は、各オペランドを(左から右に)評価し、最後のオペランドの値を返します。言い換えれば、(0, a.foo)と等価です

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

この関数は何にもアタッチされなくなったためthis、グローバルオブジェクトwindowです。そのためtrue、呼び出し時にコンソールにログインします(0, a.foo)()


console.log(this === window);開発コンソールで実行すると、印刷のログが記録されなくなります。
kushdilip

2
これは私の心を吹き飛ばしていました。ここで重要なのは、カンマ演算子が「最後のオペランドの値を返す」ということです。ここでの「値」は、それ自体を含む親がない関数自体です。したがって、fooはaの内部には存在しません。
martinp999
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.