This question already has answers here:
JavaScript closure inside loops – simple practical example
                                
                                    (44个答案)
                                
                        
                                5年前关闭。
            
                    
我尝试搜索此问题,并从遇到for循环问题的人员那里发现了许多问题,并且仅返回最后一个元素。尽我所能,我只是不明白我在做什么错。

我对Javascript真的很陌生,所以我认为关闭有问题吗?我正在写的东西应该从Urbandictionary API返回的JSON中获取一些数据。 JSON提取有效,但是我的for循环无法使用该数据构建div。

function word(term, def, example)
    {
      this.term = term;
      this.def = def;
      this.example = example;
     }

var lexicon = ['highway+salute', 'score', 'ya+heard+me', 'utz'];

var color = ['reddy', 'bluey', 'greeny', 'tanny', 'darky'];

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

$.getJSON('http://api.urbandictionary.com/v0/define?term=' + lexicon[i],
    function(data){
        lillyLivered = [];
        lillyLivered.push(new word(data.list[0].word, data.list[0].definition, data.list[0].example));
        console.log(lillyLivered);

        $('.container-fluid').html('<div class="row message unread">' +
        ' <div class="col-xs-12 col-sm-6 col-lg-3 malok ' + color[i] + ' id="">' +
        '<div class="row dict">' +
        '<div class="col-xs-9 col-sm-9 col-lg-9">' +
        '<h3 class="term term0">' +
        lillyLivered[i].term +
        '</div><div class="col-xs-3 col-sm-3 col-lg-3">' +
        '<div class="col-xs-3 col-sm-3 col-lg-3">' +
        ' <span class="step size-32"><i class="icon ion-ios7-world"></i></span>' +
        '</div></div>' +
        '<div class="row dict"><div class="col-xs-12 col-sm-12 col-lg-12">' +
        '<p class="definition definition0">' +
        lillyLivered[i].def +
        '</p><p class="eg eg0">' +
        lillyLivered[i].example +
        '</p></div></div></div>'
        );
    }
)};


我在这里摆弄:http://jsfiddle.net/orenthal/5X96B/

如果我使用lillyLivered[0],则此代码有些起作用。如果使用lillyLivered[i],则根本不会加载。我收到以下错误:

Uncaught TypeError: Cannot read property 'term' of undefined (anonymous function)


我对此感到困惑。 lillyLivered的控制台输出仅显示lillyLivered数组中索引位置2处的项目。在这种情况下,“你听到了我”:

lillyLivered
[ word
    def: "Do you understand me? [ya heard] popular in New Orleans. the phrase is suppose to come after a sentence."
    example: "Say brah, I'm chillin here in Orlando, ya heard me. ↵-C-murder's innocent, ya heard me."
    term: "ya heard me"


我以为可能存在问题,因为对lillyLivered[i].term等的调用与对JSON数据的调用包含在同一for循环中?因此,我尝试通过两个循环进行此操作。

我创建了一个新的for循环,该循环将负责创建div并从lillyLivered数组输出项目,但在这里遇到了同样的问题。

Uncaught TypeError: Cannot read property 'term' of undefined


但这有助于解决其中一个问题,即lillyLivered的控制台输出现在列出了词典中的所有四个单词以及它们的定义和示例。

lillyLivered
[word, word, word, word]


我在这里摆弄着一个小提琴:
http://jsfiddle.net/orenthal/5bTrJ/

我感觉到自己很密集,这里缺少一些明显的东西。

最佳答案

是的,您的问题与关闭有关。在发送所有请求之后很长一段时间,您的get请求很可能会完成(并调用它们各自的回调)。因此,在调用回调时,i将等于lexicon.length。您可以通过将get请求包含在其自身的功能范围中,然后将索引i传递到该范围中来解决此问题。像这样:

for (var i = 0; i < lexicon.length; i++) {
    (function(i) {
        $.getJSON('http://api.urbandictionary.com/v0/define?term=' + lexicon[i],
            function(data){
                lillyLivered = [];
                lillyLivered.push(new word(data.list[0].word, data.list[0].definition, data.list[0].example));
                console.log(lillyLivered);

                $('.container-fluid').html('<div class="row message unread">' +
                ' <div class="col-xs-12 col-sm-6 col-lg-3 malok ' + color[i] + ' id="">' +
                '<div class="row dict">' +
                '<div class="col-xs-9 col-sm-9 col-lg-9">' +
                '<h3 class="term term0">' +
                lillyLivered[i].term +
                '</div><div class="col-xs-3 col-sm-3 col-lg-3">' +
                '<div class="col-xs-3 col-sm-3 col-lg-3">' +
                ' <span class="step size-32"><i class="icon ion-ios7-world"></i></span>' +
                '</div></div>' +
                '<div class="row dict"><div class="col-xs-12 col-sm-12 col-lg-12">' +
                '<p class="definition definition0">' +
                lillyLivered[i].def +
                '</p><p class="eg eg0">' +
                lillyLivered[i].example +
                '</p></div></div></div>'
                );
            }
        )};
    }(i));
}


另一个答案也提到了关于lillyLivered的一个要点。

编辑:
由于:D的需求很高,您还可以使用forEach方法来清理代码并解决问题:

lexicon.forEach(function(lexItem, i){
            $.getJSON('http://api.urbandictionary.com/v0/define?term=' + lexItem, // lexItem === lexicon[i]
                function(data){
                    lillyLivered = [];
                    lillyLivered.push(new word(data.list[0].word, data.list[0].definition, data.list[0].example));
                    console.log(lillyLivered);

                    $('.container-fluid').html('<div class="row message unread">' +
                    ' <div class="col-xs-12 col-sm-6 col-lg-3 malok ' + color[i] + ' id="">' +
                    '<div class="row dict">' +
                    '<div class="col-xs-9 col-sm-9 col-lg-9">' +
                    '<h3 class="term term0">' +
                    lillyLivered[i].term +
                    '</div><div class="col-xs-3 col-sm-3 col-lg-3">' +
                    '<div class="col-xs-3 col-sm-3 col-lg-3">' +
                    ' <span class="step size-32"><i class="icon ion-ios7-world"></i></span>' +
                    '</div></div>' +
                    '<div class="row dict"><div class="col-xs-12 col-sm-12 col-lg-12">' +
                    '<p class="definition definition0">' +
                    lillyLivered[i].def +
                    '</p><p class="eg eg0">' +
                    lillyLivered[i].example +
                    '</p></div></div></div>'
                    );
                }
            )};
});

07-26 05:50