简体   繁体   English

为什么我将数组值设为“未定义”

[英]why I'm getting array values as “undefined”

I'm a rookie in node.js so I apologize if my question is immature .Basically I'm trying to iterate thorough an array of values for performing certain operation but I don't know why I'm getting the values as undefined . 我是node.js的菜鸟,所以我很抱歉我的问题还不成熟。基本上,我正在尝试遍历用于执行某些操作的一组值,但是我不知道为什么我得到的值是undefined

Code: 码:

for (var i = 0; i < array.length; ++i) {
    console.log(array[i]); //At this point I'm getting values without any problem
    var sQ = {
        _tag: array[i],
        _pid: data.change_caption_post_mail,
        time: data.change_caption_post_time,
    };

    db.collection('tags')
        .find(sQ)
        .count({}, function(error, numOfDocs) {
            if (error) throw err;
            console.log(array[i]);
            //But here I'm getting values as **undefined**
        });
}

Replace 更换

var i = 0; i < array.length; ++i

by 通过

let i = 0; i < array.length; i++

and you're done. 到此为止。

for (let i = 0; i < array.length; i++) {
    console.log(array[i]); //At this point I'm getting values without any problem
    var sQ = {
        _tag: array[i],
        _pid: data.change_caption_post_mail,
        time: data.change_caption_post_time,
    };

    db.collection('tags')
        .find(sQ)
        .count({}, function(error, numOfDocs) {
            if (error) throw err;
            console.log(array[i]);
            // i will be array.length here in all your callbacks
        });
}

Cause of the problem: lack of understanding scope 问题原因:缺乏了解scope

Check this example to understand the problem: 检查此示例以了解问题:

var creates function scope var创建function scope

 var funcs = [] for (var i = 0; i < 10; i++) { funcs.push(function() { console.log(i) }) } funcs.forEach(function(func) { func() }) 

While you might expect this forEach loop to result in number 0 to 9 being printed, instead you get ten times 10 . 尽管您可能希望此forEach循环导致打印09 ,但您会得到10乘以10 The cause of this is the variable i being declared using var keyword, which creates a function scope that leads to each function in funcs holding a reference to the same i variable. 原因是使用var关键字声明了变量i ,该变量创建了一个function scope ,该function scope导致funcs每个function持有对相同 i变量的引用 At the time the forEach loop is executed, the previous for -loop has ended and i holds 10 (9++ from the last iteration). 在执行forEach循环时,前一个for循环已结束,并且i持有10(最后一次迭代的9 ++)。

Compare how ES6's let , which creates block scope instead of function scope , behaves in this regard: 比较一下ES6的let ,它创建block scope而不是function scope在这方面的表现:

let (ES6 or officially ES2015 ) creates block scope : let (ES6或正式的ES2015 )创建block scope

 var funcs = [] for (let i = 0; i < 10; i++) { funcs.push(function() { console.log(i) }) } funcs.forEach(function(func) { func() }) 

Because let creates block scope , each iteration of the for loop has its "own" variable i . 因为let创建了block scope ,所以for循环的每个迭代都有其“自己的”变量i

ES5 solution using an IIFE wrapper 使用IIFE包装器的ES5解决方案

If you need an ES5 solution, an IIFE ( i mmediately i nvoked f unction e xpression) wrapper would be the way to go: 如果你需要一个ES5液,IIFE( mmediately nvoked˚FË上的表达)的包装将是要走的路:

 var funcs = [] for (var i = 0; i < 10; i++) { funcs.push((function(value) { return function() { console.log(value) } }(i))) } funcs.forEach(function(func) { func() }) 

Here, i is passed as a parameter to each function which stores its own copy value . 在这里, i作为参数传递给每个存储自己的副本value

The same is true for for..in loops: for..in循环也是如此:

 var funcs = [], obj = { first: "first", last: "last", always: "always" } for (var key in obj) { funcs.push(function() { console.log(key) }) } funcs.forEach(function(func) { // outputs: "always", "always", "always" func() }) 

Again, all functions in funcs hold the reference to the same key because var key creates a function scope that lives outside of the for..in loop. 同样,在所有功能funcs保持reference相同的key ,因为var key创建功能范围是生活在外面for..in循环。 And again, let produces the result you'd probably rather expect: 再一次, let产生您可能希望得到的结果:

 var funcs = [], obj = { first: "first", last: "last", always: "always" } for (let key in obj) { funcs.push(function() { console.log(key) }) } funcs.forEach(function(func) { func() }) 

Also compare the excellent (!) book 同时比较优秀的(!)书

Nicholas C. Zakas: "Understanding ES6" , no starch press, p. 尼古拉斯·扎卡斯(Nicholas C. Zakas):“ Understanding ES6” (不理解ES6) ,第8页。 8-9. 8-9。

from which the examples were taken. 以此为例。

Change var i = 0 to let i = 0 . var i = 0更改为let i = 0

for (let i = 0; i < array.length; ++i) {
console.log(array[i]); //At this point I'm getting values without any problem
var sQ = {
    _tag: array[i],
    _pid: data.change_caption_post_mail,
    time: data.change_caption_post_time,
};

db.collection('tags')
    .find(sQ)
    .count({}, function (error, numOfDocs) {
        if (error) throw err;
        console.log(array[i]);
    });

} }

NB When the callback function ( function (error, numOfDocs) {...} ) is executing the for loop is finished. 注意:当回调函数( function (error, numOfDocs) {...} )正在执行时,for循环完成。 if we declare var i then i is equal to array.length when executing callback so, array[array.length] returns undefined. 如果我们声明var i那么在执行回调时i等于array.length ,因此array [array.length]返回未定义。 One of the solutions is to use ES6 let which will create callback's block scope i for each iteration. 解决方案之一是使用ES6 let ,它将为每次迭代创建回调的块作用域i

The problem is that in your callback function, the reference of i remains only one which is already changed by the time callback is called. 问题是在您的回调函数中, i的引用仅保留一个在调用回调时已更改的引用。

you can change your code to 您可以将代码更改为

for (var i = 0; i < array.length; ++i) {
    (function(){
    var index = i;
    console.log(array[index]); //At this point I'm getting values without any problem
    var sQ = {
        _tag: array[index],
        _pid: data.change_caption_post_mail,
        time: data.change_caption_post_time,
    };

    db.collection('tags')
        .find(sQ)
        .count({}, function(error, numOfDocs) {
            if (error) throw err;
            console.log(array[index]);
            //But here I'm getting values as **undefined**
        });
    })();
}

it should work fine with this tweak 通过这种调整应该可以正常工作

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我得到的var undefined - Why I'm getting the var undefined Javascript数组未定义......我不确定为什么 - Javascript array is undefined… and I'm not sure why 当我尝试从javascript中的嵌套数组访问元素时,为什么会变得未定义? - Why I'm getting undefined when I tried to access the element from nested array in javascript? 我在Ionic中得到一个未定义的变量,我不确定为什么吗? - I'mg getting an undefined variable in Ionic and I'm not sure why? 为什么我使用布尔对象变得不确定? - Why i'm getting undefined using Boolean object? 为什么我的javascript数组从java对象中获取未定义的值? - Why is my javascript Array getting undefined values from a java object? 我试图从 ES 类参数创建一个数组,但我得到一个空数组,为什么? - I'm trying to create an array from ES class arguments but I'm getting an empty Array, why? 为什么我在以下ES6 for循环中得到“未定义不是函数”? - Why I'm I getting “undefined is not a function” in the following ES6 for loop? 我不知道为什么我在这里得到“无法读取未定义的属性&#39;长度&#39;的错误”错误 - I can't figure out why I'm getting the “Cannot read property 'length' of undefined” error here 为什么我得到未定义的对象,以及如何使用NodeJ解析json数据? - why I'm getting undefined object and How do I parse json data with NodeJs?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM