带有回调函数的Javascript数组

10

我尝试更好地理解JavaScript。这里是我从JavaScript函数闭包中阅读到的一段代码。

var funcs = [];
// create a bunch of functions
for (var i = 0; i < 3; i++) {
   funcs.push(function() {
    console.log(i);
   })
}
// call them
for (var j = 0; j < 3; j++) {
  funcs[j]();
}

数组funcs具有一个推送回调函数。我不知道在循环J中,为什么funcs[j]()会调用这个函数并将i打印到控制台上。
我尝试通过添加一些控制台消息来理解这个顺序:

var funcs = [];
console.log("start");
for (var i = 0; i < 3; i++) {
  console.log("i:" + i);
  funcs.push(function(){
    console.log(i);
  })
}

console.log("J loop");
for (var j=0; j<3; j++) {
  console.log("j:" + j);
  funcs[j]();
}

如预期一样,所有三个函数都会输出 3
我的问题是:为什么 funcs[j]() 能调用 funcs.push(...) 函数? 我理解 funcs[j] 是引用了 funcs 数组的第 j 个元素。但是为什么加上括号 () 就能够调用 push(...) 函数呢?


1
它不调用.push()函数;它调用传递给.push()的函数,即带有console.log(i);的小函数。 - Pointy
@Pointy,你能再解释一下吗?这就是我感到困惑的地方。为什么它会调用传递给.push()的函数?这是语法还是其他什么东西? - Shaohao
1
.push 在数组末尾添加元素。在第一个循环中,您将一个函数推送到数组中。在第二个循环中,您使用()调用该函数,[]表示索引。 - Darlyn
2
可能与你困惑的不同,上面的代码也存在一个问题,即 i 的值可能会让你感到惊讶:https://dev59.com/v3RB5IYBdhLWcg3wAjNH - T.J. Crowder
2个回答

11

function() {console.log(i);} 是一个表达式,它评估为打印 i 的函数。

funcs.push 是一个将值添加到数组中的函数。

在函数后面放置 () 将调用该函数。

funcs.push(some_value) 调用 push 函数,并将 some_value 作为要放入数组的值传递进去。

funcs.push(function() {console.log(i);}) 添加到该数组的是这个函数。

funcs[0] 的值成为该函数。

在函数后面放置 () 将调用该函数。

funcs[0]() 调用数组中第一个值为函数的函数。


1
感谢您提供逐步解释!非常有帮助! - Shaohao
在一个函数后面加上()会始终调用push()中的任何函数吗? - Shaohao
1
在函数后面加上 () 将调用该函数。在表示被推入数组的函数的东西后面加上它将调用该函数。 - Quentin

-1
首先,变量“i”是全局的,并且在循环结束时,i=3。 然后,在funcs内部的函数中使用变量“i”,然后所有函数都在控制台打印“3”。
也许你想要这样做:
var funcs = [];
console.log("start");
for (var i = 0; i < 3; i++) {
  console.log("i:" + i);
  funcs.push(function(i){
    console.log(i);
  })
}

console.log("J loop");
for (var j=0; j<3; j++) {
  console.log("j:" + j);
  funcs[j](j);
}

1
谢谢你的回答,但我并不难理解为什么它会打印三次“3”。我只是对为什么“()”会调用“console.log(i)”函数感到困惑。@Quentin做了很好的解释。 - Shaohao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接