javascript - sintaxis - sublime text php
Cómo reparar el error jslint ''No hacer funciones dentro de un bucle''? (6)
Estoy trabajando en hacer que todo nuestro código JS pase a través de jslint, a veces con muchos ajustes con las opciones para obtener el código heredado pasar por ahora con la intención de corregirlo más tarde.
Hay una cosa de la que jslint se queja por la que no tengo un workround. Es cuando se utilizan construcciones como esta, obtenemos el error ''No hacer funciones dentro de un bucle''.
for (prop in newObject) {
// Check if we''re overwriting an existing function
if (typeof newObject[prop] === "function" && typeof _super[prop] === "function" &&
fnTest.test(newObject[prop])) {
prototype[prop] = (function(name, func) {
return function() {
var result, old_super;
old_super = this._super;
this._super = _super[name];
result = func.apply(this, arguments);
this._super = old_super;
return result;
};
})(prop, newObject[prop]);
}
}
Este ciclo forma parte de una implementación JS de herencia clásica en la que las clases que amplían las clases existentes retienen la propiedad súper de la clase extendida al invocar a un miembro de la clase extendida. Solo para aclarar, la implementación anterior está inspirada en esta publicación del blog de John Resig.
Pero también tenemos otras instancias de funciones creadas dentro de un bucle.
La única solución hasta el momento es excluir estos archivos JS de jslint, pero nos gustaría usar jslint para la validación de código y la comprobación de sintaxis como parte de nuestra integración continua y flujo de trabajo de compilación.
¿Hay una mejor manera de implementar funcionalidades como esta o hay alguna manera de modificar código como este a través de jslint?
(Acabo de tropezar con estas preguntas muchos meses después de que se publicó ...)
Si realiza una función en un bucle, se crea una instancia de una función para cada iteración del bucle. A menos que la función que se está realizando sea de hecho diferente para cada iteración, entonces use el método de poner el generador de funciones fuera del ciclo; hacerlo no es solo Vajilla, sino que permite a los demás que leen su código saber que esa era su intención .
Si la función es en realidad la misma función asignada a diferentes valores en una iteración (u objetos producidos en una iteración), entonces necesita asignar la función a una variable con nombre, y usar esa instancia singular de la función en la asignación dentro del lazo:
handler = function (div_id) {
return function() { alert(div_id); }
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = handler(div_id);
}
Mayor comentario / discusión sobre esto fue hecho por otros más inteligentes que yo cuando hice una pregunta similar aquí en : error JSlint ''No hagas funciones dentro de un bucle''. lleva a la pregunta sobre el Javascript mismo
En cuanto a JSLint: Sí, es dogmático e idiomático. Dicho esto, generalmente es "correcto": descubro que muchas personas que vocalizan negativamente sobre JSLint en realidad no entienden (las sutilezas de) Javascript, que son muchas y obtusas.
Douglas Crockford tiene una nueva forma idiomática de lograr lo anterior: su antigua técnica consistía en utilizar una función interna para unir las variables, pero la nueva técnica usa un generador de funciones. Ver diapositiva 74 en las diapositivas a su charla "Funcionalidad al máximo" . [Este slideshare ya no existe]
Para los perezosos, aquí está el código:
function make_handler(div_id) {
return function () {
alert(div_id);
};
}
for (i ...) {
div_id = divs[i].id;
divs[i].onclick = make_handler(div_id);
}
JSLint es solo una guía, no siempre tiene que cumplir con las reglas. La cuestión es que no estás creando funciones en un bucle en el sentido al que se refiere. Solo crea sus clases una vez en su aplicación, no una y otra vez.
Literalmente, resuelva el problema haciendo lo siguiente:
- Crea un archivo
.jshintrc
Agregue la siguiente línea a su archivo
.jshintrc
{"loopfunc" : true, // tolerate functions being defined in loops }
Si está utilizando JQuery, es posible que desee hacer algo como esto en un bucle:
for (var i = 0; i < 100; i++) {
$("#button").click(function() {
alert(i);
});
}
Para satisfacer a JSLint, una forma de evitar esto es (en JQuery 1.4.3+) utilizar el argumento de datos del manejador adicional para .click()
:
function new_function(e) {
var data = e.data; // from handler
alert(data); // do whatever
}
for (var i = 0; i < 100; i++) {
$("#button").click(i, new_function);
}
Solo mueve tu:
(function (name, func) {...})()
bloquear fuera del ciclo y asignarlo a una variable, como:
var makeFn = function(name, func){...};
Luego, en el ciclo tenemos:
prototype[prop] = makeFn(...)