2016-12-04 57 views
1

我需要将一个数组中的字符串复制到另一个数组中的循环中创建的值。最后当我打印的时候,所有的名字都是名字数组中的最后一个。我想复制/克隆值,以便我没有参考,我希望它只在没有外部库的本机JavaScript。使用与纯javascript的数组中的闭包

这是我的代码

var exp_names =["name1","name2","name3"]; 
var i;  
for (i = 0; i < exp_names.length; i++) { 
    d3.tsv("data/"+exp_names[i], function(data) { 
     data.forEach(function(d){ 
      //Do stuff with my tsv 
      d.expId = exp_names[i]; 
     }); 
    }); 
}); 

然后所有expId是 “NAME3”

数据正确加载每个文件。

我已经尝试过jQuery的扩展函数和lodash的克隆函数,我试过自己的克隆函数并且没有任何作用,它仍然会为所有expId抛出“name3”。

这些没有工作:

var newname = new String(exp_names[i]); 
var newname = $.extend(true, {}, exp_names[i]); 
var newname = $.extend({}, exp_names[i]); 
var newname = _.clone(exp_names[i]); 
var newname = exp_names[i].slice(0); 

我绝望到现在。

+0

写请您输入数组预期的结果exp_names –

回答

1

您需要使用bind函数。

var exp_names =["name1","name2","name3"]; 
var i; 
var func = [];  
for (i = 0; i < exp_names.length; i++) { 
    func[i]=(function(index){ 
     d3.tsv("data/"+exp_names[index], function(data) { 
      data.forEach(function(d){ 
       //Do stuff with my tsv 
       d.expId = exp_names[index]; 
      }); 
     }); 
    }).bind(this,i); 
} 
for(i = 0; i < 3; i++){ 
    func[i](i); 
} 

另一种解决方案是使用let关键字。

ES6提供了这个确切的情况let关键字。我们可以使用let来设置循环范围变量,而不是使用闭包。

请试试这个:

for (let i = 0; i < exp_names.length; i++) { 
    d3.tsv("data/"+exp_names[i], function(data) { 
     data.forEach(function(d){ 
      //Do stuff with my tsv 
      d.expId = exp_names[i]; 
     }); 
    }); 
} 
+0

非常感谢你的“让”关键字帮了我很多!绑定没有工作,也没有还送环路,也许我写的东西错了。但无论如何“让”保存了一天。谢谢! –

+0

不客气。 –

+0

@ZloySmiertniy,现在必须努力'.bind'方法。 –

0

我猜IIFE的使用,并结合在一起,在第一个答案是一点都不奇怪。最好选择其中之一。由于in the newest versions of the browsers bind is way faster than an IIFE closurelet关键字我可能会建议你bind的方式。

一个类似的例子,你的情况可能是因为folows;

var exp_names = ["name1","name2","name3"], 
 
      lib = {doStg: function(d,cb){ 
 
          cb(d); 
 
         } 
 
       }, 
 
     data = [{a:1},{a:2},{a:3}]; 
 

 
for (i = 0; i < exp_names.length; i++) { 
 
    lib.doStg(data, function(i,d) { 
 
         d.forEach(function(e){ 
 
            //Do stuff with doStg 
 
            e.expId = exp_names[i]; 
 
            console.log(e); 
 
           }); 
 
        }.bind(null,i)); 
 
}