开发者

JSLint Error Report - Whats wrong with this?

I got this error and dont know what could be the cause. Any idea?

Problem at line 2127 character 18: Bad for in variable 'sport'. for (sport in sugested_sports)

                // make array
        var sugested_sports = data.split(",");

            // pr开发者_如何转开发e build DIV
        var sporty_items = '';
        for (sport in sugested_sports)
        {
            if  (sugested_sports.hasOwnProperty(sport)) {
                sporty_items += '<a href="#'+identifier[1]+'">'+sugested_sports[sport]+'</a>';
            }
        }
            // insert DIV
        DIVsuggestions.html(sporty_items);

thx alot.


Try

var sport;
for (sport in sugested_sports)

This takes care of the missing variable declaration and places it outside the for loop ( see jsLint error "Cannot set property 'first' of undefined" ).


Pointy's answer is probably the one that lint is complaining about.


As a general rule you though, you should be careful when using for (... in ...). People often confuse this construct with foreach from C#, or other similar concepts in other languages, when in fact it isn't related. The javascript for in construct iterates every member of the object -- rather than just values in a collection -- including methods and properties. This behaviour can often lead to unexpected side effects if you aren't aware of how it works beforehand.

For example:

x = ['one', 'two'];
for (var value in x) {
  alert(value);
}

That yields two alerts, the first contaning 0 and the second 1, notably the indexes of the collection.

If we change that up a bit:

x = ['one', 'two'];
x.method = function() {};
for (var value in x) {
  alert(value);
}

We end up with three alerts this time, 0, 1, and method. This is the unexpected behaviour I was referring to. It's fine to use in if you know what it does, but I've seen it catch people out on more than one occasion.

The following works with both examples:

x = ['one', 'two'];
for (var i = 0; i < x.length; i++) {
  alert(i);
}


All the error means in JSHint/JSLint is that you didn't declare your key/iterator variable. As @Christopher suggests, JSLint wants you to declare it at the top of its scope (google JavaScript hoisting for more on hoisting, like this link):

/*global data, identifier, DIVsuggestions */
// We'll pretend all of the above were passed in from a function's parameters
// by using JSLint's "global" keyword -- now you can paste this code into
// jslint.com and have it pass muster.

// make array
var sugested_sports = data.split(","),
    sporty_items = '', // pre build DIV
    sport; // <<<<  **** DECLARE YOUR "KEY" HERE ****

for (sport in sugested_sports)
{
    if  (sugested_sports.hasOwnProperty(sport)) {
        sporty_items += '<a href="#'+identifier[1]+'">'
            +sugested_sports[sport]+'</a>';
    }
}
// insert DIV
DIVsuggestions.html(sporty_items);

This bad for in variable error here reduces to the same as a 'sport' was used before it was defined error elsewhere.


EDIT: It's worth mentioning that if your for is in an internal function, you need to declare your for in variable in that same context. JSLint will complain if you declare the for in in the parent context.

Example:

function spam(d)
{
    var fnTest, row; // `row` is defined "too early"

    fnTest = function (data) {
        for (row in data)
        {
            if (data.hasOwnProperty(row))
            {
                console.log(data.row);
            }
        }
    };

    fnTest(d);
}

To make things happy, move row into the internal function. Even though it was technically still in scope, JSLint doesn't like the "superscope" that was used before.

function spam(d)
{
    var fnTest;

    fnTest = function (data) {
        var row; // and JSLint is happy! ;^D
        for (row in data)
        {
            if (data.hasOwnProperty(row))
            {
                console.log(data.row);
            }
        }
    };

    fnTest(d);
}


By the way, James' concern is covered by the hasOwnProperty check the OP has inserted. Take out that check, and JSLint will complain, "The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype". Here's a little more on hasOwnProperty with for... in, if you're interested.


var sugested_sports = data.split(","),
    sport,
    sport_items = '';

    for (sport in sugested_sports)
    {
        // 
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜