Dlaczego jakikolwiek kod JavaScript chce „wyciąć powiązanie”?

10

Powód korzystania z

(0, foo.fn)();

jest wycięcie powiązania : thisnie będzie już związane, fooale będzie powiązane z obiektem globalnym.

Ale jaki jest powód, dla którego dowolny kod JavaScript (lub kod JS Google) chce wyciąć powiązanie? (i czy jest to anty-wzór, czy nie?)

niepolarność
źródło
nazywanie tego wiązaniem nie wydaje się właściwe. bindmetoda wiąże. To tylko zmiana kontekstu. Nie możesz wyciąć ani stracić wiązania (więź utworzona przez bind).
marzelin
może ten kod jest generowany przez transpiler z jakiegoś funkcjonalnego języka (clojurescript?), który ma określone wymagania, jeśli chodzi o wywoływanie funkcji?
marzelin
możliwy duplikat Dlaczego Babel przepisuje zaimportowane wywołanie funkcji na (0, fn) (…)? - lub gdzie jeszcze to widzisz?
Bergi,
Wydaje mi się, że widziałem to w kodzie Google'a i być może w niektórych ramach, takich jak Angular, React lub inne… nie mogę sobie przypomnieć, gdzie i czasem jest to
zminimalizowane

Odpowiedzi:

8

Ten rodzaj kodu jest zwykle generowany przez transpilatory (takie jak Babel), w celu konwersji nowoczesnego JavaScript - który korzysta z najnowszych dodatków do specyfikacji - na wersję JavaScript, która jest szerzej obsługiwana.

Oto przykład, w którym występuje ten wzór transpilacji:

Powiedzmy, że mamy ten oryginalny kod przed transpilacją:

import {myfunc} from "mymodule";
myfunc();

Aby kod ten był zgodny z ES5, możesz to zrobić:

"use strict";    
var mymodule = require("mymodule");    
mymodule.myfunc();

Ale tutaj wykonalibyśmy myfuncz mymoduleasthis wartości, która nie dzieje się w oryginalnym kodzie. I mimo, że może nie zawsze być problem, to lepiej, aby upewnić się, że zachowuje się funkcja podobnie jak miałoby to w oryginalnej wersji , nawet jeśli ta funkcja będzie używać thisReference - jak nietypowe lub nawet bezużyteczne, że stosowanie thisw myfuncmoże być ( ponieważ również w oryginalnej wersji byłoby undefined).

Na przykład, jeśli oryginalny kod this.memberFun()zgłasza błąd z powodu odwołania w funkcji, to również wrzuci transpilowaną wersję.

Tak więc operator przecinka służy do pozbycia się tej różnicy:

(0, mymodule.myfunc)();

To prawda, że ​​w kodzie, który sam piszesz, nigdy nie miałbyś dobrego przypadku użycia dla tego wzorca, ponieważ nie byłby używany thisw myfuncpierwszej kolejności.

trincot
źródło
W jaki sposób jest requirezwiązany z ES6 lub ES5? Kiedyś myślałem, że tym wymaganiem jest moduł węzła.
connexo
requirejest rzeczywiście funkcją dostępną w węźle lub dostępną w bibliotekach takich jak browserify, wymagają.js itp. Nie jest to szczególnie związane z ES5 / 6. Z drugiej strony konstrukcja języka ES6 +, taka jak, importnie może zostać przeniesiona do ES5 bez czegoś takiego jak transpilacja.
trincot,
więc jeśli skondensuję go do kilku wierszy podsumowania: jeśli jest to biblioteka lub moduł, który zawiera wiele funkcji, które nie są tak naprawdę metodami ani OO (w formie modA.fn1), to te funkcje naprawdę nie powinny używać, thisale jeśli przypadkiem tak, nie chcemy, thisaby wpływał on na moduł w jakikolwiek sposób jako efekt uboczny, więc przerywamy wiązanie, aby zachowywał się tak, jak powinien, jeśli jest niezależną funkcją
nonpolarity
Tak, tak właśnie można to podsumować. Ponownie, dotyczy to głównie transpilatorów, a nie kodera.
trincot,