Babel içe aktarılan işlev çağrısını (0, fn) (…) neden yeniden yazıyor?


100

Gibi bir girdi dosyası verildiğinde

import { a } from 'b';

function x () {
  a()
}

babel bunu derleyecek

'use strict';

var _b = require('b');

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

ancak gevşek modda derlendiğinde işlev çağrısı şu şekilde çıkar: _b.a();

Bunu açıklayan bir yorum olması umuduyla virgül operatörünün nereye eklendiğine dair biraz araştırma yaptım. Eklemekten sorumlu olan kod burada .


4
Onlar yapmalıydık _b.a.call()niyeti açıklığa kavuşturmak.
Bergi

@Bergi (0,) kullanmalarının nedeninin aktarılan kodda yer kazanmak olduğuna eminim.
Andy


Yanıtlar:


138

(0, _b.a)()işlevin set ile genel nesneye (veya katı mod etkinleştirilmişse, to ) _b.açağrılmasını sağlar . Doğrudan arayacaksanız , ayarlı olarak çağrılır .thisundefined_b.a()_b.athis_b

(0, _b.a)(); eşdeğerdir

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

( ,virgül operatörüdür, bkz. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comma_Operator ).


3
bağlantı için teşekkürler. bunu defalarca geçti ve sonunda ne olduğunu bulmaya karar verdi.
theflowersoftime

@RobW Dosyanın var _a = (0, _b.a)en üstüne eklemeyi düşünürdüm ve sonra aramanın _abirçok durumda daha fazla alan kazandıracağını düşünürdüm, bunu yapmadıkları hakkında herhangi bir fikir?
Andy

1
@Andy Önerinizin yan etkileri olabilir, örneğin _b.a(dinamik) alıcı olduğunda.
Rob W

@RobW Görüyorum, yani fikre fonksiyonun çağrılması gerekene kadar olası yan etkilerden kaçınmak olduğunu söylüyorsunuz.
Andy

Modüllerin her zaman katı kodlar olduğuna dikkat edin, bu yüzden her zaman geçerlidir this === undefinedve küresel nesneden bahsetmenize bile gerek yoktur
Bergi

22

Virgül operatörü, işlenenlerinin her birini (soldan sağa) değerlendirir ve son işlenenin değerini döndürür.

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

Öyleyse bir örnek görelim:

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

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

Şimdi, fooyöntemde thiseşittir a(çünkü fooeklenmiştir a). Yani a.foo(doğrudan ararsanız false, konsolda oturum açacaktır .

Ama eğer ararsan (0, a.foo)(). İfade (0, a.foo), işlenenlerinin her birini (soldan sağa) değerlendirecek ve son işlenenin değerini döndürür. Başka bir deyişle, (0, a.foo)eşdeğerdir

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

Bu işlev artık hiçbir şeye bağlı olmadığından this, küresel nesnedir window. Bu yüzden truearadığınızda konsolda oturum açar (0, a.foo)().


geliştirici console.log(this === window);konsolunda çalıştırmak artık günlük yazdırmıyor.
kushdilip

3
Bu aklımı uçuruyordu. Buradaki anahtar, Virgül işlecinin "son işlenenin değerini döndürmesidir" - buradaki "değer", işlevin kendisinin içerdiği ebeveyni yoktur - yani foo artık a'nın içinde yaşamaz.
martinp999
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.