2011-09-29 7 views
37

estoy usando ReSharper 6 y Métodos Web ASP.NET y tienen una advertencia irritante en mis archivos Javascript:ReSharper, Javascript: "El uso de manera implícita declaró variable global 'X'"

"Use of implicitly declared global variable 'X'" 

La razón es que el método web se crea en Javascript como:

new X.example().webMethod(arg1, arg2, successCallback, failureCallback); 

Y X ... está implícitamente definido. Me pregunto si hay una solución para definir esto explícitamente. Está definido en algún archivo JS autogenerado, creado por el material del framework de métodos web de ASP.NET.

Mi pregunta es: ¿cómo me deshago del error para esta situación, sin deshacerme de él para situaciones legítimamente incorrectas?

Gracias!

+0

Buena pregunta. Parece una advertencia extraña porque esa línea en sí misma no declara nada. Si X no está definido, obtendrá un error en el tiempo de ejecución; si X se declara en otro lugar, deberías recibir la advertencia en otro lugar. – nnnnnn

+2

Es el motor R # JS que dice "Oye, no reconozco X - ¿X realmente debería estar aquí?" Tiene mucho sentido en los casos en que escribe "XY", pero realmente significa "X" y R # guarda su tocino. El problema es que no veo una manera de decirle a R # "sí, ¡esto realmente DEBERÍA estar aquí!" – rythos42

+2

¿Todavía se queja si cambia 'X' a' window.X'? Una idea alternativa: en C#, puede envolver una línea problemática en '// resharper disable whatever' y' // resharper enable whatever' (no recuerdo exactamente), por lo que espero que hagan algo similar para js. O podría definir explícitamente la variable en el ámbito global: 'var X = window.X || {}; '. – sethobrien

Respuesta

37

Al usar símbolos (funciones, constantes, variables globales) definidos en otros archivos JavaScript, los paso a la "función de alcance" del archivo actual (función de alto nivel, generalmente anónimo, que evita la contaminación global del espacio de nombres) como parámetros:

multiple containers

Como se puede ver en la captura de pantalla, ReSharper (6.0.2202.688) está contento con jQuery, ContainerA y ContainerB a pesar de que no se definen en cualquier parte del archivo actual. El comentario en la línea 1 está solo ahí para JSLint (sin errores).

Esta técnica supone que todos los demás archivos JavaScript siguen el JavaScript mejores prácticas de mínimamente contaminar el espacio de nombres global mediante la definición de un único objeto de nivel superior que contiene todos los ( públicos) símbolos exportados (es decir jQuery es la única mundial objeto para la biblioteca jQuery y sus complementos, ContainerA es el único objeto global para LibraryA, ContainerB es el único objeto global para LibraryB, etc.).

Debido a que claramente no tiene control sobre los métodos Web ASP.NET generar funciones constructoras en espacio de nombres global, en su caso de tener que recurrir al recipiente final, window:

window as a container

Esto es una ligera variación en la técnica sugerida por @sethobrien en su comentario. Una ventaja importante (en mi humilde opinión) es que no está codificando window.X en su código. En cambio, su código está creando instancias de clases desde el contenedor aspNet (que en este momento es sinónimo de window, pero que podría cambiar en el futuro). Además, tener aspNet.X en el código declara su intención más claramente para las personas que leerán su código en el futuro. Finalmente, las variables locales pueden acortarse mediante minimizadores de JavaScript produciendo archivos ligeramente más pequeños que se transmiten a los navegadores de los clientes.

+0

Salvo una solución real de JetBrains, creo que esta es la mejor idea hasta ahora. Realmente estaba esperando una directiva de procesador, ala JSLint/JSHint :). Dicho esto: me gusta mucho la parte "aspNet.X declara su intención". Muchas gracias por la idea! – rythos42

+0

No lo entiendo ¿Cómo escribiría una función de JavaScript Button_onclick que llama a 'X'? – comecme

+1

¿Qué sucede si su javascript está en el medio de una página .aspx? ¿Puedes agregar el/* global */comentario a tu página aspx justo antes del script? He intentado esto y Resharper todavía me está advirtiendo acerca de un error. (Supongo que Resharper está usando reglas similares para encontrar errores como JsLint para su Javascript) –

4

Agregando el siguiente al inicio de su archivo de script ///<refernce path="my.js" /> (my.js es el archivo donde se define X) probablemente reparará esta advertencia ya que ReSharper comenzará a ver esta variable global.

De lo contrario, para minimizar los cambios, puede agregar var X = window.X; cerca de la parte superior del archivo. Intente hacerlo para no contaminar el espacio de nombres global y asegúrese de que no confunda el código que realmente crea una instancia de X en la ventana.

+2

Esto no ayuda: los archivos JS son generados automáticamente por el framework ASP.NET y no tengo un archivo para referenciar. – rythos42

+0

Hice algo similar, pero hago referencia a un archivo JS "falso" que en realidad no se usa en producción. Añado, a mano, los globales que necesito para evitar que ReSharper se queje. Esto debería funcionar bien si tiene un conjunto pequeño de variables globales definidas. –

6

Tiene exactamente el mismo problema después de mover a Jasmine a un paquete Bower externo y excluir el código de Jasmine del proyecto VS. Resharper inmediatamente comenzó a quejarse en Use of an implicitly declared global variable 'describe' y así sucesivamente.

Lo resolví agregando al proyecto otro archivo llamado workaround.js definiciones ficticias para las variables. En su caso sería:

// This is a workaround for R# complaining on undefined global variables. 
// In practice they come from and are defined by external frameworks, so 
// this is not a real issue. 

var X = function() { }; 

Y esto es un archivo en mi proyecto - https://gist.github.com/barahilia/62871d9219cee825d82e.

+0

Intenté esto para angular, y por cualquier razón tuve que vincular la variable global a la variable de ventana. Probablemente debido al orden de guiones en el archivo html. var angular = window.angular; – Casey