为什么console.log在这段代码中返回undefined ?

Why console.log in this code return undefined?

本文关键字:代码 返回 undefined log console 段代码 为什么      更新时间:2023-09-26
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]+'"]');
    });
};

当您单击该元素时,i的值将增加到anchors.length的值。

你的点击处理程序有一个对i的引用。

JavaScript中无法解析的属性查找返回undefined

使用this作为元素的引用会容易得多。否则,找到一种方法通过值传递i的值,而不是直接引用它。

未定义的原因是i实际上等于5。看看这个:

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

现在,在这个循环完成后,你会认为i在这个时间点上是未定义的,因为它应该是for循环的局部值。不幸的是,事实并非如此。一个简单的测试方法:

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

简单地说,for循环的i++在真值测试部分(i < 5位)之后执行。因此,当i等于4时,循环运行,然后它被i++加1,这将i的值设置为5,从而使真值测试失败。

那么现在你知道i等于5,当你在anchors数组中查找时,anchors[5]是未定义的。

这很重要的原因是每次触发click事件时,它将执行i的缓存值5,并且反过来,您将始终记录未定义

为了解决这个问题,我们可以为i的值创建一个别名,如下所示
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 );
};

变量i获得上次循环的值。如果你想访问锚,你可以使用:

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