50

I'm using Resharper 6 and ASP.NET Web Methods and have an irritating warning in my Javascript files:

"Use of implicitly declared global variable 'X'"

The reason is that the web method is created in Javascript as:

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

And X...is implicitly defined. I'm wondering if there is a solution to explicitly define this? It's defined in some auto-generated JS file, created by the ASP.NET web method framework stuff.

My question is: how do I get rid of the error for this situation, without getting rid of it for legitimately wrong situations?

Thanks!

rythos42
  • 1,217
  • 2
  • 11
  • 27
  • Good question. That seems a strange warning because that line on its own doesn't declare anything. If X isn't defined you'll get an error at runtime; if X is declared elsewhere you should get the warning elsewhere. – nnnnnn Sep 30 '11 at 01:05
  • 2
    It's the R# JS engine saying "Hey, I don't recognize X - should X really be here?" It makes a lot of sense in cases where you type "XY" but really meant "X" and R# saves your bacon. The problem is that I don't see a way of telling R# "yes, this really SHOULD be here!" – rythos42 Sep 30 '11 at 18:33
  • 2
    Does it still complain if you change `X` to `window.X`? An alternate idea: in C#, you can wrap a problem line in `//resharper disable whatever` and `//resharper enable whatever` (I don't remember exactly), so I expect they'd do something similar for js. Or you could explicitly define the variable in the global scope: `var X = window.X || {};`. – sethobrien Nov 05 '11 at 08:38
  • 2
    Those are good ideas, sethobrien! "window." removes the complaint, although it isn't quite as nice looking. I think I was hoping for a JSHint/JSLint style /*globals section to explicitly say "Yeah, I know that this is defined elsewhere." – rythos42 Nov 10 '11 at 20:29

4 Answers4

46

When using symbols (functions, constants, global variables) defined in other JavaScript files, I pass them to the current file's "scoping function" (top-level, usually anonymous, function that prevents global namespace pollution) as parameters:

multiple containers

As you can see from the screenshot, ReSharper (6.0.2202.688) is happy with jQuery, ContainerA and ContainerB even though they are not defined anywhere in the current file. The comment in line 1 is only there for JSLint (no errors).

This technique assumes that all the other JavaScript files follow the JavaScript best practice of minimally polluting the global namespace by defining a single top-level object that contains all the exported (public) symbols (i.e. jQuery is the only global object for jQuery library and its plugins, ContainerA is the only global object for LibraryA, ContainerB is the only global object for LibraryB, etc).

Because you clearly don't have control over ASP.NET Web Methods generating constructor functions into global namespace, in your case you have to resort to the ultimate container, window:

window as a container

This is a slight variation on the technique suggested by @sethobrien in his comment. An important (IMHO) advantage is that you're not hard-coding window.X into your code. Instead, your code is instantiating classes from the aspNet container (that at the moment happens to be a synonym for window, but that might change in the future). Also, having aspNet.X in the code declares your intention more clearly for people who will read your code in the future. Finally, local variables can be shortened by JavaScript minimizers yielding slightly smaller file transmitted to client browsers.

Milan Gardian
  • 11,326
  • 5
  • 38
  • 45
  • Barring an actual solution from JetBrains, I think this is the best idea yet. I was really hoping for a processor directive, ala JSLint/JSHint :). That said - I really like the "aspNet.X declares your intention" part. Thanks very much for the idea! – rythos42 Nov 17 '11 at 18:46
  • I don't get it. How would I write a javascript function Button_onclick which calls `X`? – comecme Jun 06 '12 at 19:43
  • 1
    What happens if your javascript is in the middle of an .aspx page? Can you add the /*global */ comment to your aspx page just before the script? Have tried this and Resharper is still warning me about an error. (I'm assuming Resharper is using similar rules to find errors as JsLint for its Javascript) – Stephen Price Jul 22 '13 at 07:45
  • This didn't work for me. I may have mistyped something, I admit I'm not following the logic here. – Mike K Jan 18 '18 at 20:28
  • 1
    For the common problem of jQuery's '$' I riffed on this answer and added the comment "// global $: false" and the related warnings are gone. – William T. Mallard Sep 16 '21 at 20:42
8

Adding following to the top of your script file ///<reference path="my.js" /> (my.js is the file where X is defined) will likely fix this warning since ReSharper start seeing this global variable.

Otherwise to minimize changes you can add var X = window.X; near the top of the file. Try to make it not to polute global namespace and make sure it will not confuse code that actually instantiates X on the window.

R. Schreurs
  • 8,587
  • 5
  • 43
  • 62
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 2
    This doesn't help - the JS files are auto-generated by the ASP.NET framework and I don't have a file to reference. – rythos42 Nov 17 '11 at 18:45
  • I did something similar, but I references a "fake" JS file that's not actually used in production. I add, by hand, those globals that I need to keep ReSharper from complaining. This should work OK if you have a small set of defined globals. – Tom Winter Jan 29 '15 at 16:25
  • 1
    Just now I fixed the typo in `refernce`. This helps. You must put these references right at the top of the file, even above `"use strict";`. – R. Schreurs Nov 28 '19 at 12:37
7

Got exactly the same problem after moving Jasmine to an external Bower package and excluding Jasmine's code from VS project. Resharper immediately started complaining on Use of an implicitly declared global variable 'describe' and so on.

I solved this by adding to the project another file named workaround.js dummy definitions for the variables. In your case it would be:

// 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 () { };

And this is a file in my project - https://gist.github.com/barahilia/62871d9219cee825d82e.

Ilia Barahovsky
  • 10,158
  • 8
  • 41
  • 52
  • I tried this for angular, and for whatever reason I had to bind the global variable to the window variable. Probably due to script order in the html file. var angular = window.angular; – Casey Plummer Jul 17 '16 at 01:24
1

If it is an error that can be ignored you can use

// ReSharper disable once UseOfImplicitGlobalInFunctionScope
  • Thank you. Perfect answer. I was embedding the Swagger UI following their distribution download code: https://github.com/swagger-api/swagger-ui/tree/master/dist Their index.html file caused a few code inspection errors: (1) ECMAScript 5 compliance and (2) implicit global variable usage. The changes were: 1) `const ui = SwaggerUIBundle({` to `var ui = SwaggerUIBundle({` 2) added your comment before the implicit use of the global variable(s) `// ReSharper disable once UseOfImplicitGlobalInFunctionScope var ui = SwaggerUIBundle({` – Jeremy Ray Brown Apr 20 '19 at 17:57
  • 1
    While this does work, it's a bit distracting and if there are other implicit global vars on the same line it will mask those. It's even worse for the enable and restore Resharper comments. I was able to use the comment "// global $: false" (sans quotes naturally) – William T. Mallard Sep 16 '21 at 20:38