Uso adecuado de const para definir funciones

Resuelto David Sinclair asked hace 9 años • 6 respuestas

¿Existe algún límite en cuanto a los tipos de valores que se pueden establecer consten JavaScript y, en particular, las funciones? ¿Es esto válido? Es cierto que funciona, pero ¿se considera una mala práctica por algún motivo?

const doSomething = () => {
   ...
}

¿Deberían definirse todas las funciones de esta manera en ES6? No parece que esto haya tenido éxito, si es así.

David Sinclair avatar Oct 09 '15 21:10 David Sinclair
Aceptado

No hay ningún problema con lo que has hecho, pero debes recordar la diferencia entre declaraciones de funciones y expresiones de funciones.

Una declaración de función, es decir:

function doSomething () {}

Se eleva completamente a la parte superior del alcance (y lettambién consttienen alcance de bloque).

Esto significa que lo siguiente funcionará:

doSomething() // works!
function doSomething() {}

Una expresión de función, es decir:

[const | let | var] = function () {} (or () =>

Es la creación de una función anónima ( function () {}) y la creación de una variable, y luego la asignación de esa función anónima a esa variable.

Entonces, las reglas habituales sobre el levantamiento de variables dentro de un alcance: las variables con alcance de bloque ( lety const) no se elevan hasta undefinedla parte superior de su alcance de bloque.

Esto significa:

if (true) {
    doSomething() // will fail
    const doSomething = function () {}
}

Fallará ya que doSomethingno está definido. (Arrojará un ReferenceError)

Si cambia a usar, varobtendrá la elevación de la variable, pero se inicializará para undefinedque el bloque de código anterior aún no funcione. (Esto generará un mensaje TypeErrorya que doSomethingno es una función en el momento en que lo llames)

En lo que respecta a las prácticas estándar, siempre debes utilizar la herramienta adecuada para el trabajo.

Axel Rauschmayer tiene una excelente publicación sobre alcance y elevación, incluida la semántica de es6: Variables y alcance en ES6

tkone avatar Oct 09 '2015 14:10 tkone

Aunque usar constpara definir funciones parece un truco, tiene grandes ventajas que lo hacen superior (en mi opinión).

  1. Hace que la función sea inmutable, por lo que no tiene que preocuparse de que algún otro fragmento de código cambie esa función.

  2. Puede utilizar la sintaxis de flecha gruesa, que es más corta y limpia.

  3. El uso de funciones de flecha se encarga del thisenlace por usted.

ejemplo confunction

// define a function
function add(x, y) { return x + y; }

// use it
console.log(add(1, 2)); // 3

// oops, someone mutated your function
add = function (x, y) { return x - y; };

// now this is not what you expected
console.log(add(1, 2)); // -1
Expandir fragmento

mismo ejemplo conconst

// define a function (wow! that is 8 chars shorter)
const add = (x, y) => x + y;

// use it
console.log(add(1, 2)); // 3

// someone tries to mutate the function
add = (x, y) => x - y; // Uncaught TypeError: Assignment to constant variable.
// the intruder fails and your function remains unchanged
Expandir fragmento

gafi avatar Mar 15 '2017 07:03 gafi

Han pasado tres años desde que se hizo esta pregunta, pero recién ahora me estoy encontrando con ella. Dado que esta respuesta está tan abajo en la pila, permítame repetirla:

P: Me interesa saber si existen límites sobre los tipos de valores que se pueden establecer usando const en JavaScript, en particular funciones. ¿Es esto válido? Es cierto que funciona, pero ¿se considera una mala práctica por algún motivo?

Me motivé a investigar un poco después de observar a un prolífico codificador de JavaScript que siempre usa constdeclaraciones para functions, incluso cuando no hay ninguna razón/beneficio aparente.

En respuesta a "¿ se considera una mala práctica por algún motivo? ", permítame decir, en mi opinión, sí lo es, o al menos, el uso de declaraciones tiene ventajasfunction .

Me parece que esto es en gran medida una cuestión de preferencia y estilo. Hay algunos buenos argumentos presentados anteriormente, pero ninguno tan claro como se hace en este artículo:

Confusión constante: por qué sigo usando declaraciones de funciones de JavaScript por medium.freecodecamp.org/Bill Sourour, gurú, consultor y profesor de JavaScript.

Insto a todos a leer ese artículo, incluso si ya han tomado una decisión.

Estos son los puntos principales:

Las declaraciones de función tienen dos ventajas claras sobre las expresiones de función [const]:

Ventaja n.º 1: claridad de intenciones

Al escanear miles de líneas de código al día, es útil poder descubrir la intención del programador de la forma más rápida y sencilla posible.

Ventaja #2: Orden de declaración == orden de ejecución

Idealmente, quiero declarar mi código más o menos en el orden en que espero que se ejecute.

Esto es lo mejor para mí: cualquier valor declarado usando la palabra clave const es inaccesible hasta que la ejecución lo alcance.

Lo que acabo de describir arriba nos obliga a escribir código que parece al revés. Tenemos que comenzar con la función de nivel más bajo y avanzar hacia arriba.

Mi cerebro no funciona de esa manera. Quiero el contexto antes que los detalles.

La mayor parte del código está escrito por humanos. Por lo tanto, tiene sentido que el orden de comprensión de la mayoría de las personas siga aproximadamente el orden de ejecución de la mayor parte del código.

JMichaelTX avatar Jun 26 '2018 01:06 JMichaelTX

Hay casos especiales en los que arrow functionssimplemente no funcionan:

  1. Si estamos cambiando un método de una API externa y necesitamos la referencia del objeto.

  2. Si necesitamos usar palabras clave especiales que sean exclusivas de la functionexpresión: arguments, yield, bindetc. Para más información: Limitaciones de la expresión de la función de flecha

Ejemplo:

Asigné esta función como controlador de eventos en la HighchartsAPI. Lo activa la biblioteca, por lo que la thispalabra clave debe coincidir con un objeto específico.

export const handleCrosshairHover = function (proceed, e) {
  const axis = this; // axis object
  proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // method arguments
};

Con una función de flecha, thiscoincidiría con el alcance de la declaración y no tendremos acceso al objeto API:

export const handleCrosshairHover = (proceed, e) => {
  const axis = this; // this = undefined
  proceed.apply(axis, Array.prototype.slice.call(arguments, 1)); // compilation error
};

realraif avatar Oct 22 '2020 13:10 realraif