¿Por qué algún código JavaScript quiere "cortar el enlace"?

10

La razón de usar un

(0, foo.fn)();

es cortar el enlace : thisya no estará vinculado foosino que estará vinculado al objeto global.

Pero, ¿cuál es la razón por la cual cualquier código JavaScript (o el código JS de Google) querría cortar el enlace? (¿y es un antipatrón o no?)

nonopolaridad
fuente
llamarlo vinculante no se siente bien. bindmétodo vincula. Aquí es solo un cambio de contexto. No puede cortar ni perder la encuadernación (el vínculo creado por bind).
marzelin
¿Tal vez este código es generado por un transpilador de algún lenguaje funcional (clojurescript?) que tiene requisitos específicos cuando se trata de llamar a funciones?
marzelin
posible duplicado de ¿Por qué Babel reescribe la función importada llamada a (0, fn) (...)? ¿O dónde más estás viendo esto?
Bergi
Creo que lo vi en el código de Google y posiblemente en algún marco como Angular, React u otros ... no puedo recordar dónde y, a veces, se minimiza
polaridad

Respuestas:

8

Este tipo de código generalmente es generado por transpiladores (como Babel), para convertir JavaScript moderno, que utiliza las adiciones más recientes a la especificación, a una versión de JavaScript que es más compatible.

Aquí hay un ejemplo donde ocurre este patrón de transpilación:

Digamos que tenemos este código original antes de la transpilación:

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

Para hacer este código compatible con ES5, puede hacer esto:

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

Pero aquí debemos ejecutar myfunccon mymodulecomo thisvalor, que no está ocurriendo en el código original. Y aunque eso no siempre sea un problema, es mejor asegurarse de que la función se comporte como lo haría en la versión original , incluso si esa función usara una thisreferencia: cuán inusual o incluso inútil podría ser ese uso de thisin myfunc( porque también en la versión original sería undefined).

Entonces, por ejemplo, si el código original arrojaría un error debido a una this.memberFun()referencia en la función, también arrojará la versión transpilada.

Entonces es donde se usa el operador de coma para deshacerse de esa diferencia:

(0, mymodule.myfunc)();

De acuerdo, en el código que escribes tú mismo, nunca tendrías un buen caso de uso para este patrón, ya que no lo usarías thisen myfuncprimer lugar.

trincot
fuente
¿Cómo se requirerelaciona con ES6 o ES5? Solía ​​pensar que require es un módulo de nodo.
connexo
requirees, de hecho, una función disponible en el nodo o proporcionada en bibliotecas como browserify, require.js, ... etc. No está específicamente relacionado con ES5 / 6. Por otro lado, una construcción de lenguaje ES6 + como importno se puede transferir a ES5 sin algo como la transpilación.
trincot
así que si se condensa en varias líneas de un resumen: si se trata de una biblioteca o módulo que incluye muchas funciones que no son realmente métodos u OO, (en forma de modA.fn1), entonces estas funciones realmente no deberían usarse, thispero si por accidente lo hacen, no queremos thisque afecte el módulo de ninguna manera como un efecto secundario, por lo que cortamos el enlace, hacemos que se comporte como debería comportarse si es una función independiente
polaridad
Sí, así es como podrías resumirlo. Nuevamente, esto es principalmente una preocupación para los transpiladores, no tanto para un codificador.
Trincot