tipos - pasar parametros a una funcion javascript desde html
Orden de función de JavaScript: ¿por qué es importante? (4)
Pregunta Original:
JSHint queja cuando mi JavaScript llama a una función que está definida más abajo en la página que la llamada a la misma. Sin embargo, mi página es para un juego y no se invocan funciones hasta que todo se haya descargado. Entonces, ¿por qué las funciones de orden aparecen en mi código?
EDITAR: Creo que puedo haber encontrado la respuesta.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Estoy gimiendo por dentro. Parece que necesito pasar OTRO día reordenando seis mil líneas de código. La curva de aprendizaje con javascript no es empinada en absoluto, pero es muy loooooong.
Hay demasiadas personas empujando reglas arbitrarias sobre cómo se debe escribir JavaScript. La mayoría de las reglas son basura absoluta.
El izado de funciones es una característica de JavaScript porque es una buena idea.
Cuando tiene una función interna que a menudo es la utilidad de las funciones internas, agregarla al comienzo de la función externa es un estilo aceptable de escritura de código, pero tiene el inconveniente de que tiene que leer los detalles para llegar a la función externa lo hace.
Debes apegarte a un principio en toda la base de código, ya sea poner funciones privadas primero o último en tu módulo o función. JSHint es bueno para imponer consistencia, pero debe ajustar ABSOLUTAMENTE el .jshintrc para que se ajuste a sus necesidades, NO ajustar su código fuente a los conceptos de codificación extravagantes de otras personas.
Puede evitar un estilo de codificación que pueda ver en la naturaleza, ya que no le brinda ventajas y solo un posible dolor de refactorización:
function bigProcess() {
var step1,step2;
step1();
step2();
step1 = function() {...};
step2 = function() {...};
}
Esto es exactamente lo que la función de elevación está ahí para evitar. Simplemente aprende el idioma y explota sus puntos fuertes.
La razón principal probablemente sea que JSLint solo hace una pasada en el archivo, por lo que no sabe que definirá dicha función.
Si usó la sintaxis de la declaración de funciones
function foo(){ ... }
En realidad, no existe ninguna diferencia en la que declare la función (siempre se comporta como si la declaración estuviera al principio).
Por otro lado, si su función se estableció como una variable regular
var foo = function() { ... };
Debes garantizar que no lo llamarás antes de la inicialización (esto en realidad puede ser una fuente de errores).
Como reordenar toneladas de código es complicado y puede ser una fuente de errores en sí mismo, le sugiero que busque una solución alternativa. Estoy bastante seguro de que puedes decirle a JSLint el nombre de las variables globales de antemano para que no se queje de cosas no declaradas.
Ponga un comentario sobre el comienzo del archivo
/*globals foo1 foo2 foo3*/
O puede usar un cuadro de texto para eso. (También creo que puede pasar esto en los argumentos a la función jslint interna si puede entrometerse con ella).
Solo se generan las declaraciones de función, no la expresión de función (asignación).
tl; dr Si no llamas nada hasta que todo se carga, deberías estar bien.
Editar: para obtener una descripción general que también cubre algunas declaraciones ES6 ( let
, const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_Cheatsheet
Este comportamiento extraño depende de
- Cómo defines las funciones y
- Cuando los llamas.
Aquí hay algunos ejemplos.
bar(); //This won''t throw an error
function bar() {}
foo(); //This will throw an error
var foo = function() {}
----
bar();
function bar() {
foo(); //This will throw an error
}
var foo = function() {}
----
bar();
function bar() {
foo(); //This _won''t_ throw an error
}
function foo() {}
---
function bar() {
foo(); //no error
}
var foo = function() {}
bar();
¡Esto se debe a algo llamado izar !
Hay dos formas de definir funciones: declaración de función y expresión de función. La diferencia es molesta y minúscula, así que digamos algo ligeramente erróneo: si lo estás escribiendo como function name() {}
, es una declaración , y cuando lo escribes como var name = function() {}
(o una función anónima asignada a un retorno, cosas así), es una expresión de función.
Primero, veamos cómo se manejan las variables:
var foo = 42;
//the interpreter turns it into this:
var foo;
foo = 42;
Ahora, cómo se manejan las declaraciones de funciones:
var foo = 42;
function bar() {}
//turns into
var foo; //Insanity! It''s now at the top
function bar() {}
foo = 42;
Las sentencias var
"arrojan" la creación de foo
a la parte superior, pero aún no le asigna el valor. La declaración de función viene a continuación en línea, y finalmente se asigna un valor a foo
.
¿Y qué hay de esto?
bar();
var foo = 42;
function bar() {}
//=>
var foo;
function bar() {}
bar();
foo = 42;
Solo la declaración de foo
se mueve a la cima. La asignación viene solo después de que se realiza la llamada a la bar
, donde estaba antes de que ocurriera todo el levantamiento.
Y finalmente, por concisión:
bar();
function bar() {}
//turns to
function bar() {}
bar();
Ahora, ¿qué hay de las expresiones de función?
var foo = function() {}
foo();
//=>
var foo;
foo = function() {}
foo();
Al igual que las variables regulares, el primer foo
se declara en el punto más alto del alcance, luego se le asigna un valor.
Veamos por qué el segundo ejemplo arroja un error.
bar();
function bar() {
foo();
}
var foo = function() {}
//=>
var foo;
function bar() {
foo();
}
bar();
foo = function() {}
Como hemos visto antes, solo se genera la creación de foo
, la asignación viene donde apareció en el código "original" (sin cable). Cuando se llama a la bar
, es antes de que a foo
se le asigne un valor, entonces foo === undefined
. Ahora en el cuerpo de la función de la bar
, es como si estuvieras haciendo undefined()
, lo que arroja un error.