8

El javascript, cuando se ejecuta a través de JSLint me grita y no estoy seguro de por qué.JSLint quejándose de mi try/catch

/*jslint browser: true, devel: true, evil: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, newcap: true, immed: true */ 

var foo = function() { 
    try { 
    console.log('foo'); 
    } catch(e) { 
    alert(e); 
    } 

    try { 
    console.log('bar'); 
    } catch(e) { 
    alert(e); 
    } 
}; 

foo(); 

Me dice:

Problema en la línea de 12 caracteres 11: 'e' ya está definido.

} catch(e) {

Parece ser molesto porque tengo una segunda catch(e). ¿Por qué sería esto un problema? ¿No simplemente establece e en una variable local dentro del bloque catch? ¿Necesito nombrar de manera exclusiva las variables locales para todos los errores atrapados en una función?

Respuesta

9

Para JSLint, try..catch tiene el efecto implícito de declarar e como una variable local. Como tiene dos bloques de ese tipo dentro de la misma función (no hay un alcance de bloque en JavaScript), JSLint lo ve como declarando una variable que ya ha sido declarada.

nombre para las variables e1, e2, etc. podría prevenir esta advertencia de JSLint. ¿Es realmente un problema? La especificación ECMAScript 5, sección 12.14, dice "No importa cómo el control deja el Bloque, LexicalEnvironment siempre se restaura a su estado anterior". Esto, de hecho, parece ser el caso:

try { 
    throw new Error("testing 1234"); 
} catch(fooBarBaz){ 
    alert("Catch: " + fooBarBaz); // works 
} 

alert(fooBarBaz); // throws exception 

lo tanto, para concluir, esto es simplemente una limitación de JSLint y es poco probable que conduzca a cualquier problema práctico.

+0

Parece que estás en lo cierto. Supongo que try/catch _no_ introduce scope, como lo demuestra esta prueba rápida que puse: http://jsfiddle.net/VRcwV/ –

+0

¡Oh, acabo de ver la edición! Por lo tanto, no introduce el alcance, pero la variable local creada por la declaración catch no está disponible fuera de esa captura. Entonces, ¿introduce un poco de alcance especializado solo para esa excepción? –

+1

@Squeegy: IE 8 es * no * compatible, parece. Pruebe mi prueba (http://jsfiddle.net/DpHMt/) en ese navegador, y verá * ambas * cajas de alerta abiertas. – PleaseStand

0

Trate de usar una variable diferente, tal vez se confunde porque e generalmente se reserva para los controladores de eventos.

+0

por lo que sé 'e' no está reservado. – pex

0

Utilice una variable diferente para cada intento/captura.

0

JSLint podría simplemente estar equivocado aquí. De acuerdo con las especificaciones de ECMAScript, ingresar un bloque catch crea un nuevo ámbito dentro del cual se define la variable de excepción. En su ejemplo, e es válido solo dentro del bloque catch y no está definido fuera. No hay redefinición aquí.

+1

especificaciones de ECMAScipt, seguro. Pero la implementación del navegador, al parecer no: http://jsfiddle.net/VRcwV/ –

+0

@Squeegy: Es solo la variable de excepción 'e' que entra en el nuevo ámbito. Las variables declaradas con 'var' están siempre en el alcance de la función. Intenta 'alert (e)' y verás que está indefinido fuera del bloque 'catch'. – casablanca