js函数调用的问题;

var a =[];
for(var i=0;i<4;i++){

      a[i] =function(){
        console.log(i)
    }
}
a[2]();

讲道理,函数传参不是应该在function(参数),这样吗? a【i】不应该是 函数名吗,

for(var i=0;i<4;i++){

      var a[i] =function(i){
        console.log(i)
    }
}
a[i](2);

但是是错误的,a【i】并不能作为函数名,换成a之后

for(var i=0;i<4;i++){

       a =function(i){
        console.log(i)
    }
}
a(2);

这样可以,输出2,就是正常的参数,
我现在的问题是:a[2]();这个i的值怎么来的啊,还是说调用这个函数的话需要进行for循环,这个2是给谁阿,他可以直接给这个a[i]吗。哎。。我也不知道;

。。我看不懂你们的答案,啊不知道采纳谁阿,大神看下那个说的对给说下啊,我给采纳下啊。。太菜了,,

阅读 2.5k
5 个回答

不是不能做函数名的问题。是i的取值的问题。

var a =[];
for(var i=0;i<4;i++){

      a[i] =function(){
        console.log(i)
    }
}
a[2]();

对于这个来说。你将function(){console.log(i)}存在了a数组的每一项中。调用的时候执行console.log(i),会去查找i的值。因为for的{}并不是一个作用域,所以取到的i值是循环结束后的i=4;

var a =[];//你没写这个
for(var i=0;i<4;i++){

      var a[i] =function(i){
        console.log(i)
    }
}
a[i](2);

对于这个来说同样的道理相当于a[4](2)a[4]是undefined,并不是一个函数,所以会报错a[i] is not a function
补充:
可以去看一下作用域链
举个例子

var i=1;
function test(){
console.log(i)
}
test()

执行test的时候,用到了i,所以要去查i的值。函数作用域内部没有(有的话就不去外面找了),就要去上一级作用域找,找到了i是1。输出1。

for(var i=1;i<4;i++){
}
function test(){
console.log(i)
}
test()

同样内部没有,要去外面找,而i经过for循环已经是4了,即找到的i=4,所以输出4。

for(var i=1;i<4;i++){
function test(){
console.log(i)
}
}
test()

作用域只有函数作用域。标志是{}(除非使用let,可以去看下let的相关知识)。所以就查找i值的过程,这个和上面的是一样的。

ai后面这个i就是function(i),这个i会传到function里面
a[i]这个i只是一个函数名

var a = [];
for(var i = 0;i<4;i++){
a[i] = function(i){console.log(i);}
}
a[2](2)//2 undefined
a[2](3)//3 undefined

clipboard.png

var a =[];
for(var i=0;i<4;i++){

      a[i] =function(){
        console.log(i)
    }
}
a[2]();

for循环执行后,a数组的四个元素都是函数了, i的值在当前function找不到的情况下,就往上层作用域找,明显每一个匿名函数都没有声明i,所以往外层找就是for循环里的i,当for循环执行完时i已经是4了。所以不用怀疑,不论a[0]() a[1]() ... a[3]()都是输出4;

首先你的第一个

var a =[];
for(var i=0;i<4;i++){

      a[i] =function(){
        console.log(i)
    }
}
a[2]();

当你调用 a[2]() 的时候,for循环的i已经循环到4,也就是你触发函数与赋值函数存在时间差,for循环早已循环完毕,此时可以用闭包进行解决,可已经变量i留在内存中,如果对闭包不熟悉可以百度一下。

 var a =[];
    for(var i=0;i<4;i++){
        (function(i){
            a[i] =function(){
                console.log(i)
            }
        })(i);
        
    }
    a[2]();

第二个,原理相同,此时for循环完毕之后,i=4,而你的函数只有a[0]->a[3],i=4的时候跳出循环,所以会报错,a[4]不是一个函数。

第三个就简单了,简单的赋值函数,传参调用。

希望可以帮到你

这是一个作用域的问题。js没有块级作用域(let可以,但是也相当于是闭包了)。

声明变量的时候不写var。就是在顶级声明的变量。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题