style guide guia estilo javascript reactjs ecmascript-6 eslint airbnb

javascript - guide - eslint airbnb use



¿Por qué la guía de estilo de Airbnb dice que se desaconseja confiar en la inferencia del nombre de la función? (3)

EDIT # 2: Razón encontrada de AirBnbs en su guía de estilo Javascript

No olvide nombrar la expresión: las funciones anónimas pueden dificultar la localización del problema en la pila de llamadas de un Error ( Discussion )

Respuesta original a continuación

MDN tiene un buen resumen de cómo funciona la inferencia del nombre de la función , incluidas dos advertencias:

Observaciones

Existe un comportamiento de inferencia de <function>.name no estándar en los siguientes dos escenarios:

  1. cuando se utilizan intérpretes de guiones

El intérprete de guiones establecerá la propiedad del nombre de una función solo si una función no tiene una propiedad propia llamada nombre ...

  1. cuando se usa herramienta js

Tenga cuidado al usar el nombre de función y las transformaciones del código fuente, como las llevadas a cabo por los compresores JavaScript (minificadores) u ofuscadores

....

En la versión no comprimida, el programa se ejecuta en la raíz verdadera y los registros ''foo'' es una instancia de ''Foo'', mientras que en la versión comprimida se comporta de manera diferente y se ejecuta en la rama else. Por lo tanto, si confía en Function.name como en el ejemplo anterior, asegúrese de que su canalización de compilación no cambie los nombres de las funciones o no asuma una función para tener un nombre particular.

¿Cuál es la inferencia del nombre de la función?

La propiedad del nombre devuelve el nombre de una función, o (antes de las implementaciones de ES6) una cadena vacía para funciones anónimas

function doSomething() {} console.log(doSomething.name); // logs "doSomething"

Las funciones creadas con la nueva función de sintaxis (...) o simplemente Función (...) tienen su propiedad de nombre establecida en una cadena vacía. En los siguientes ejemplos, se crean funciones anónimas, por lo que el nombre devuelve una cadena vacía

var f = function() {}; var object = { someMethod: function() {} }; console.log(f.name == ''''); // true console.log(object.someMethod.name == ''''); // also true

Los navegadores que implementan funciones ES6 pueden inferir el nombre de una función anónima desde su posición sintáctica . Por ejemplo:

var f = function() {}; console.log(f.name); // "f"

Opinión

Personalmente prefiero las funciones (flecha) asignadas a una variable por tres razones básicas:

En primer lugar, nunca uso function.name

En segundo lugar, mezclar el alcance léxico de las funciones nombradas con la asignación se siente un poco flojo:

// This... function Blah() { //... } Blah.propTypes = { thing: PropTypes.string } // ...is the same as... Blah.propTypes = { thing: PropTypes.string } function Blah() { //... } // ALTERNATIVELY, here lexical-order is enforced const Blah = () => { //... } Blah.propTypes = { thing: PropTypes.string }

Y en tercer lugar, en igualdad de condiciones, prefiero las funciones de flecha:

  • comunicar al lector que no hay this , no hay arguments etc.
  • se ve mejor (imho)
  • rendimiento (la última vez que miré, las funciones de flecha fueron marginalmente más rápidas)

EDITAR: instantáneas de memoria

Estaba escuchando un Podcast y el invitado me contó de una situación en la que tuvo que lidiar con las limitaciones del uso de las funciones de flecha con el perfil de memoria. He estado exactamente en la misma situación anteriormente.

En la actualidad, las instantáneas de memoria no incluirán un nombre de variable, por lo que puede encontrar que las funciones de flecha se convierten en funciones con nombre solo para conectar el perfilador de memoria. Mi experiencia fue bastante sencilla, y todavía estoy contento con las funciones de flecha.

Además, solo he usado instantáneas de memoria una vez, por lo que me siento cómodo renunciando a una "instrumentación" para la claridad (subjetiva) de forma predeterminada.

// bad class Listing extends React.Component { render() { return <div>{this.props.hello}</div>; } } // bad (relying on function name inference is discouraged) const Listing = ({ hello }) => ( <div>{hello}</div> ); // good function Listing({ hello }) { return <div>{hello}</div>; }

Esto se toma de la guía de estilo de reacción de Airbnb. ¿Puede alguien explicar por qué no se recomienda "confiar en la inferencia del nombre de la función"? ¿Es solo una preocupación de estilo?


Creo que esto también podría tener algo que ver con el comportamiento inesperado con el que te puedes topar implícitamente dando un nombre léxico a lo que puedes esperar que sea una función anónima.

Digamos, por ejemplo, que alguien entendió la función de flecha:

(x) => x+2;

Tener la función regular equivalente:

function(x) { return x+2; }

Sería bastante fácil esperar este código:

let foo = (x) => x+2;

Para luego ser el equivalente de:

let foo = function(x) { return x+2; }

Donde la función permanece en el anonimato y sería incapaz de hacer referencia a sí mismo para hacer cosas como la recursión.

Entonces, si en nuestra gozosa ignorancia, tuviéramos algo así:

let foo = (x) => (x<2) ? foo(2) : "foo(1)? I should be a reference error"; console.log(foo(1));

Funcionó con éxito porque esa función obviamente no era anónima:

let foo = function foo(x) { return (x<2) ? foo(2) : "foo(1)? I should be a reference error"; }

Esto podría verse agravado por el hecho de que en otras situaciones en las que Babel implícitamente agrega un nombre a funciones anónimas, (que en realidad creo que es un efecto secundario de apoyar nombres de funciones implícitas, aunque podría estar equivocado) sobre eso), manejan correctamente cualquier caso marginal y arrojan errores de referencia donde usted esperaría.

Por ejemplo:

let foo = { bar: function() {} } // Will surprisingly transpile to.. var foo = { bar: function bar() {} }; // But doing something like: var foo = { bar: function(x) { return (x<2) ? bar(2) : ''Whats happening!?''; } } console.log(foo.bar(1)); // Will correctly cause a ReferenceError: bar is not defined

Puede verificar ''ver compilado'' en esta DEMO rápida para ver cómo Babel está transpilingando eso para mantener el comportamiento de una función anónima.

En resumen, ser explícito con lo que estás haciendo es generalmente una buena idea porque sabes exactamente qué esperar de tu código. Desalentar el uso de nombres de funciones implícitas es probablemente una elección estilística en apoyo de esto mientras que también es concisa y directa.

Y probablemente alzando. Pero oye, un viaje secundario divertido.


Esto es porque:

const Listing = ({ hello }) => ( <div>{hello}</div> );

tiene un nombre inferido de Listado, mientras que parece que lo estás nombrando, en realidad no eres:

Example

// we know the first three ways already... let func1 = function () {}; console.log(func1.name); // func1 const func2 = function () {}; console.log(func2.name); // func2 var func3 = function () {}; console.log(func3.name); // func3

que tal esto?

const bar = function baz() { console.log(bar.name); // baz console.log(baz.name); // baz }; function qux() { console.log(qux.name); // qux }