为什么我只从JavaScript for循环获取最后一项? [英] Why am I only getting the last item from javascript for loop?

查看:269
本文介绍了为什么我只从JavaScript for循环获取最后一项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试过搜索这个问题,并且发现了一些问题,他们的for循环出现问题,并且只返回最后一个元素。尝试,因为我可能,我只是不明白我在做什么错在这里。



我真的很新的Javascript,所以我觉得我有一个问题关闭?我写的是应该从Urbandictionary API返回的JSON获取一些数据。 JSON获取工作,但我的 for 循环建立与该数据的div不能正常工作。

 函数词(term,def,例子)
{
this.term = term;
this.def = def;
this.example = example;
}

var lexicon = ['highway + salute','score','ya + hear + 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],
函数(data){
lillyLivered = [];
lillyLivered.push(新单词(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:无法读取undefined(匿名函数)的属性'term'

我被它弄糊涂了。 lillyLivered 的控制台输出仅显示 lillyLivered 数组中索引位置2处的项目。在这种情况下,雅听到我:

  lillyLivered 
[word
def:我呢?[听说]在新奥尔良很受欢迎,这句话应该是在一句话之后来的。
例如:说一声,我在奥兰多的这里很冷静,你听到我的声音了 - C - 谋杀无辜者,你听我说。
term:你听见了我

我以为这个问题可能是因为调用 lillyLivered [i] .term 等...被包含在与JSON数据调用相同的 for 循环中?所以我试着用两个循环做这个。



我创建了一个新的for循环,用于创建div并输出 lillyLivered 数组,但我遇到了同样的问题。

 未被捕获的TypeError:无法读取未定义的属性'term'
$ b $

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

  lillyLivered 
[word,word,word,word]

这里有一个小提琴:
http://jsfiddle.net/orenthal/5bTrJ/

我感觉到我正在密集,缺少一些非常明显的东西。

解决方案

是的,你的问题与闭包有关。在所有请求发送完毕之后,您的获取请求很可能会完成(并调用其各自的回调)。因此,在调用回调函数时, i 将等于 lexicon.length 。你可以通过在自己的功能范围内包含获取请求,并将索引 i 传递到该范围来解决这个问题。像这样:
$ b $ pre $ code> for(var i = 0; i< lexicon.length; i ++){
(function (i){
$ .getJSON('http://api.urbandictionary.com/v0/define?term='+ lexicon [i],
函数(data){
lillyLivered新的单词(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 =行字典>< 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 < code $> c code $> code $> c> lexicon.forEach(function(lexItem,i) {
$ .getJSON('http://api.urbandictionary.com/v0/define?term='+ lexItem,// lexItem === lexicon [i]
function(data){
lillyLivered = [];
lillyLivered.push(新单词(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've tried searching for this issue and have found a number of questions from people having problems with their for loops and it only returning the last element. Try as I might, I'm just not understanding what I'm doing wrong here.

I'm really new to Javascript so I think I'm having an issue with closures? What I'm writing is supposed to grab some data from the JSON returned from the Urbandictionary API. The JSON fetch works but my for loop to build divs with that data is not working properly.

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>'
        );
    }
)};

I have a fiddle up here: http://jsfiddle.net/orenthal/5X96B/

This code works somewhat if I use lillyLivered[0]. It doesn't load at all if I use lillyLivered[i]. I get the following error:

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

I'm getting confused by it. Console output of lillyLivered only shows the item at the index position 2 in the lillyLivered array. In this case "ya heard me":

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"

I thought that maybe the problem existed because of the calls to lillyLivered[i].term etc... were contained within the same for loop as the calls to the JSON data? So I tried doing this with two loops.

I created a new for loop that would take care of creating the divs and outputting the items from the lillyLivered array but I ran into the same issue here.

Uncaught TypeError: Cannot read property 'term' of undefined 

But this has helped with one of the issues, that being that the console output of lillyLivered now lists all four words from lexicon along with their definitions and examples.

lillyLivered
[word, word, word, word]

I have a fiddle of this one up here: http://jsfiddle.net/orenthal/5bTrJ/

I get the feeling that I'm being dense and missing something very obvious here.

解决方案

Yes your issue has to do with closures. Your get requests are likely finishing (and calling their respective callbacks) long after all of the requests have been sent. Because of this, by the time the callbacks are called, i will be equal to lexicon.length. You can fix this by enclosing the get request in its own functional scope and passing the index i at that moment into that scope. Like this:

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));
}

The other answer also mentions a good point about lillyLivered.

Edit: Due to high demand :D, you could also use the forEach method to clean up your code and fix your issue:

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>'
                    );
                }
            )};
});

这篇关于为什么我只从JavaScript for循环获取最后一项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆