1

Learning JS here, I run JSLint on this code:

/*jslint devel: true*/

function Animal(n) {
    "use strict";
    this.name = n;
    this.prop = "a";
}

var a = new Animal("duppa");

for (v in a) {
    if (a.hasOwnProperty(v)) {
        console.log("property:" + v);
    }
}

I get:

jslint:test2.js:11:6:'v' was used before it was defined.
jslint:test2.js:11:8:Cannot read property "kind" from undefined

jslint: ignored 0 errors.

It obviously complains that I did not declare v up front:

/*jslint devel: true*/

function Animal(n) {
    "use strict";
    this.name = n;
    this.prop = "a";
}

var a = new Animal("duppa");

var v;
for (v in a) {
    if (a.hasOwnProperty(v)) {
        console.log("property:" + v);
    }
}

This shuts JSLint up, but is it really necessary? In general I try to follow good conventions but is this one really necessary in JS? E.g. Python lives happily without such stuff (for x in range(10)... etc).

LetMeSOThat4U
  • 6,470
  • 10
  • 53
  • 93
  • 1
    possible duplicate of [When to use var in Javascript](http://stackoverflow.com/questions/5398766/when-to-use-var-in-javascript) – p.s.w.g Feb 15 '14 at 14:42
  • 2
    Python isn't JavaScript, so yes it's necessary. You could also do `for (var v in a) {...}` – David G Feb 15 '14 at 14:42
  • @0x499602D2: that's what I did at first and then JSLint complains `jslint:test2.js:11:6:Move 'var' declarations to the top of the function. jslint:test2.js:11:6:Cannot read property "line" from undefined` – LetMeSOThat4U Feb 15 '14 at 15:20
  • JSLint wants you to move it up because that's effectively where it's introduced; all variable declarations are hoisted to the top of the function in which they're declared. – user229044 Feb 15 '14 at 15:44

5 Answers5

1

Yes, you absolutely should declare the variable. Otherwise you're declaring v at global scope which is never good, but it's particularly bad for counting variables which are a single letter long like v.

Consider the case where two people get lazy about declaring a variable of the same name:

// Your code, which iterates over a nested array

var arr = [ [1, 2], [3, 4] ];

for (i = 0; i < arr.length; ++i) {
  AwesomeLibrary.doSomething(arr[i]);
}

// way down elsewhere, in awesome_library.js...

function doSomething(arr) {
  for (i = 0; i < arr.length; ++i) {
    // Now your `i` is clobbered, and we have a subtle but devastating bug
  }
}

This doesn't even require two lazy people: If you work with JavaScript long enough and refuse to declare your variables, you will eventually do this to yourself.

user229044
  • 232,980
  • 40
  • 330
  • 338
  • Yikes! This implicit global scope var creation is awful! In Python you have to explicitly declare your variable in a function as `global` otherwise you're creating local variables. :-( The Zen knows what it says: "explicit is better than implicit". – LetMeSOThat4U Feb 15 '14 at 15:36
1

There are 10 types of people in the world. Those who understand why you declare variables in javascript and those who have regular sex. (Just smile)

You must understand that every function have their own scope and you must use this scope. If you don't use declaration inside your function you change the global state, and it affects of course on many things.

So use var and don't create global variables !!!

Farkhat Mikhalko
  • 3,565
  • 3
  • 23
  • 37
0

It is always a better practice to define your variables before using them. Here javascript's for loop requires you to define i, because it is in the for loop, use

var v;
for( v in a)
CodeBird
  • 3,883
  • 2
  • 20
  • 35
  • 1
    never declare a variable in a loop, that'll fail jslint as well. – Joe Minichino Feb 15 '14 at 14:45
  • @JoeMinichino Why does it fail? – David G Feb 15 '14 at 14:46
  • Thanks for the info, don't know a lot about jslint just js, will edit – CodeBird Feb 15 '14 at 14:46
  • 1
    The point is that in javascript there's no for-loop-block scope, so declaring a variable outside the for statement shows more clearly the scope that the variable belongs to. Douglas Crockford's jslint will fail a `for (var x in y)` statement. – Joe Minichino Feb 15 '14 at 14:50
  • @JoeMinichino Wow my JS has gotten rusty over the years! Thanks for reminding me. :) – David G Feb 15 '14 at 15:27
  • @JoeMinichino: wait what?! in `for() { block }` the `{ block }` is not a separate scope? But I've read in the intro to The Important Book that JS has lexical scoping? :-( – LetMeSOThat4U Feb 15 '14 at 15:48
0

Remember that JSLint doesn't complain because of some obscure academic reason but because it protects you from major problems your application may potentially suffer from.

You declare a variable to contain the variable in the current scope. It's a safeguard for you and your program as well making it more readable code (global vars appearing out of nowhere are always confusing).

Imagine if you had a global variable v in your application and then used the same nomenclature (v) for iteration in a function. Javascript will automatically assume that the global variable is being used and you'll find yourself with unwanted values in your global. Having said that, the less stuff you put in the global namespace the better.

Joe Minichino
  • 2,793
  • 20
  • 20
0

As far as my understanding goes, if you use a variable without declaring it within a function scope, it gets declared in the global scope, which isnt a best practice. You will soon cloud your global scope with variables.

//This creates a global variable
function not_a_best_practice(){
    a=10;
}

//This creates a local variable
function not_bad(){
    var a=20;
}

This answer may throw more light on the discussion at hand: What is the scope of variables in JavaScript?

Community
  • 1
  • 1