在javascript中处理循环,只有最后一项受到影响?

Unk*_*own 5 javascript closures

我正在使用处理图像处理的gm npm模块.我有这个代码.

for(i=0;i < 4;i++){
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " created  ::  " + arguments[3]); //success
    });
}
Run Code Online (Sandbox Code Playgroud)

这个循环意味着循环遍历图像阵列并裁剪每张照片,但它只裁剪最后一张.我认为它可以执行函数调用和回调,但尚未针对该级别进行.

Min*_*hev 7

将您的代码更改为:

for (var i = 0; i < 4; i++) {
  (function (i) {
    gm("www/img/" + image[i]).crop(550, 406, 0, 0).write(function(err) {
         console.log(this.outname + " created  ::  " + arguments[3]); //success
    });
  }).call(this, i);
}
Run Code Online (Sandbox Code Playgroud)

否则i每次调用回调时,值将为3.


Roy*_*mir 5

您需要在变量上创建一个“闭包”

Js有一个函数作用域。

for (i = 0; i < 4; i++)
{
    (function (a)
    {
        gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
        {
            console.log(this.outname + " created  ::  " + arguments[3]); //success
        });
    }).call(this,i)
}
Run Code Online (Sandbox Code Playgroud)

或者

that=this;

for (i = 0; i < 4; i++)
    {
        (function (a)
        {
            gm("www/img/" + image[a]).crop(550, 406, 0, 0).write(function (err)
            {
                console.log(that.outname + " created  ::  " + arguments[3]); //success
            });
        })(i)
    }
Run Code Online (Sandbox Code Playgroud)

编辑 :

另外 - 我还会保留arguments从现在起,在 IIFE 之后的引用 - 参数正在发生变化。

你可以保留你的arguments通过:

var args= Array.prototype.slice.apply(arguments)

例子 :

function g()

{
for (i = 0; i < 4; i++)
    {
        (function (a)
        {
           console.log(arguments); //huh ? arguments are not a,b,c !!! anymore
        })(i);
    }
}


g('a','b','c') // 0,1,2,3
Run Code Online (Sandbox Code Playgroud)

所以你确实需要保留对参数的引用,因为它们在 IIFE 之后发生了变化。