user2194521
user2194521

Reputation: 119

Why console.log in this code return undefined?

var el = $('.container');
var anchors = new Array('jobs', 'portfolio', 'docs', 'interier', 'price');
for (var i = 0; i < anchors.length; i++) {
    el.on('click', 'a[href$="#'+anchors[i]+'"]', function (e) {
        e.preventDefault();
        console.log(anchors[i]);
        $.scrollTo('a[name="'+anchors[i]+'"]');
    });
};

Upvotes: 1

Views: 296

Answers (3)

Armin
Armin

Reputation: 15978

The variable i got the value of the last loop. If you want to access the anchor you can use this:

 console.log($(this).attr('href').substr(1));

Upvotes: 0

whitneyit
whitneyit

Reputation: 1226

The reason you are getting undefined is because i is actually equal to 5. Take a look at this:

for ( var i = 0; i < 5; i++ ) {
    console.log( i );
}

Now after that loop has completed you would think that i would be undefined at this point in time because it should be local to the for loop. Unfortunately, this is not the case. A simple way to test this:

for ( var i = 0; i < 5; i++ ) {
    console.log( i );
}

console.log( i ) // Logs out 5;

Put simply, the i++ of the for loop gets executed after the truth test part, the i < 5 bit. So when i is equal to 4, the loop runs, and afterwards it gets incremented by i++, which sets the value of i to 5, which in turn fails the truth test.

So now that you know i is equal to 5, when you do the lookup in your anchors array, anchors[5] is undefined.

The reason this is important is because every time a click event fires, it will execute the cached value for i which is 5, and in turn, you will always log undefined

To fix this, we can create an alias to the value of i like so

var el = $('.container');
var anchors = new Array('jobs', 'portfolio', 'docs', 'interier', 'price');

for (var i = 0; i < anchors.length; i++) {

    // By passing the value to this self executing function,
    // it creates a new instance of the variable
    ( function ( index ) {
        el.on('click', 'a[href$="#'+anchors[index]+'"]', function (e) {
        e.preventDefault();
            console.log(anchors[index]);
            $.scrollTo('a[name="'+anchors[index]+'"]');
        });
    })( i );

};

Upvotes: 1

alex
alex

Reputation: 490667

When you click that element, i will have been incremented to the value of anchors.length.

Your click handler has a reference to i.

An unresolved property lookup in JavaScript returns undefined.

It would be much easier to use this as a reference to the element. Otherwise, find a way to pass the value of i by value, not a direct reference to it.

Upvotes: 3

Related Questions