views:

348

answers:

6

I am checking if a variable is defined or not, and if it is not defined explicitly I am going to define it by doing:

if ( typeof(aVariable) == 'undefined' ) {
  var aVariable = value;
}

Because the variable is not defined JSLint warns that it is used before it is defined, and that is exactly what I want.

What is the best practice to overcome this?

Update

I want to enable defining those variables explicitly doing this:

<script>
  var aVariable = value;
</script>
<script src="myScript.js"></script>

So everyone who is going to include this script can customize some of the properties. And I am afraid I cannot change this logic because it is already being used in hundred of web sites this way.

+4  A: 

I think what JSLint is telling you is that you shouldn't use variables before they are defined. If you are happy that it is appropriate in your scenario - you can ignore that warning. If you aren't absolutely sure, have another think about why this variable isn't defined yet.

For example, do you really want to test if aVariable has a value set, rather than is or isn't defined?

var aVariable = null;

... (sometime later)

if (aVariable == null) {
  aVariable = value;
}
Sohnee
+1  A: 

Try this:

aVariable = null;

aVariable = typeof(aVariable) == 'undefined' ? null : value;
Sarfraz
A: 

That error seems to be triggered when you use camel casing for your variable name. If you start the variable with a capital letter (Variable) or make it all lower case (variable), you just get the "implied global" error.

I'm not sure what it's trying to suggest by enforcing casing on your variable name, though you always have to take JSLint with a grain of salt. What you're doing here is perfectly valid and a good practice to avoid accidentally using undefined variables.

Jimmy Cuadra
Question: *JSLint warns that it is used before it is defined*. How is that related to camel case? And it's *not* perfectly valid, because JSLint is right: The variable *is* used before it is defined.
Boldewyn
Read my answer more thoroughly before down voting. It is related to the casing of the variable name the OP used: `aVariable`. Run the same code posted in the question with the variable name written as `avariable`, `AVARIABLE`, or `Avariable` and you'll notice JSLint no longer displays the error.
Jimmy Cuadra
So, which JSLint do you use? The one over at http://www.jslint.com/ gives the same result independent from spelling because it has *nothing to do with spelling*.
Boldewyn
I am not sure how you are getting different results from me. I don't use a "different" JSLint. I just tried it again and had the same result. Copy/paste the OP's code exactly, then change `typeof(aVariable)` to `typeof(avariable)` and you will see the error `'aVariable' was used before it was defined.` no longer shows up. I agree that spelling is insignificant as far as how the variable is treated. I am just pointing out the behavior of JSLint in reporting errors.
Jimmy Cuadra
@Jimmy Cuadra: I pasted the first code snippet into JSLint on the home page of jslin.com, got the *JSLint warns that it is used before it is defined* error, changed both instances of `aVariable` to `avariable`, reran JSLint and got exactly the same error. Perhaps you forgot to change the variable name on both lines?
Tim Down
+3  A: 

You could make the variable (it's global anyway) an explicit member of window:

window.aVariable = 'default';

and later

if (! ('aVariable' in window)) {
    window.aVariable = 'new value';
}

If you don't want or cannot change the code, then I'd suggest the pragmatic ansatz and to ignore JSLint's complaints, since your code will work anyways (that is, as long as you don't enable ECMAScript 5's strict mode...).

Boldewyn
A: 

Easiest to declare your variables before you make any use of them:

var aVariable;

This will be initialized with type "undefined", so the undefined test will still work:

if (typeof aVariable == "undefined") {
    aVariable = value;
}
Tim Down
A: 

I found more acceptable answers in JSLint mailing list, sorry about that Boldewyn :)

Solution 1

In IE, at a script level (i.e. per file, or per script block), if it sees a "var" declaration during its parse phase (before execution), it will reset the value of that variable if it already existed.

So better would be to simply do this:

/*global foo: true */
if (typeof foo === "undefined") {
foo = "some value";
}

By not declaring "var" and simply assigning foo, foo will automatically get global scope.

Solution 2 (special case)

If explicitly set variable is not zero or false

var foo = foo || "some value";
nimcap