javascript - jshintrc - jslint vs jshint
JSLint afirma que ciertas llamadas a funciones recursivas están "fuera del alcance" (2)
Tengo un fragmento de Javascript con una llamada a función recursiva:
(function () {
"use strict";
var recurse = function (x) {
if (x <= 0) {
return;
}
return recurse(x - 1);
};
recurse(3);
}());
Esto no hace más que llamarse a sí mismo unas pocas veces, pero se ejecuta.
Pegar lo anterior en JSLint me da este error:
''recurse'' is out of scope.
Sin embargo, si pego en el siguiente fragmento, (usando una declaración de función en lugar de var):
(function () {
"use strict";
function recurse(x) {
if (x <= 0) {
return;
}
return recurse(x - 1);
}
recurse(3);
}());
JSLint lo ama, sin errores.
Sé que el objetivo de JSLint es evitar errores en el código Javascript. ¿Alguien sabe por qué JSLint cree que el primero es malo Javascript? ¿Qué error estoy previniendo al no hacer una llamada recursiva de la primera manera?
Cuando define la función, la variable recurse aún no está definida, por eso JSLint dice que está fuera del alcance, afirmando que puede estar indefinido y ese punto.
No hay nada de malo con ninguno de los estilos. Por lo que puedo decir, esta es una advertencia inapropiada.
El problema parece ser que una declaración de variable que incluye una asignación no hace que JSLint registre la presencia del nombre de la variable declarada en el alcance hasta que se evalúa toda la asignación. Es decir, cuando JSLint lee var recurse = ...
, no se da cuenta de que recurse
es una variable declarada hasta que evalúa el lado derecho de la asignación. En este caso, el lado derecho incluye una función que hace uso de la variable declarada recurse
, pero JSLint aún no sabía acerca de la existencia de recurse
, porque no había terminado de analizar la asignación completa.
Tenga en cuenta que este código funciona exactamente igual que su ejemplo var
pero no produce advertencias en JSLint:
(function () {
"use strict";
var recurse;
recurse = function (x) {
if (x <= 0) {
return;
}
return recurse(x - 1);
};
recurse(3);
}());
Al extraer var recurse
como una instrucción separada, JSLint primero descubre que recurse
se declara en el ámbito actual y luego analiza la asignación. Con su combinada var recurse = ...
(que, una vez más, no está mal), JSLint analiza erróneamente la tarea primero y luego aprende acerca de la existencia de recurse
.