我需要将数组中的字符串复制到循环中创建的另一个数组中的值。最后,当我打印所有名称是名称数组中的最后一个。我想复制/克隆值,以便我没有引用,我希望它只在没有外部库的本机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都是&#34; name3&#34;
每个文件正确加载数据。
我已尝试使用jquery的扩展功能以及lodash的克隆功能,我已经尝试了自己的克隆功能,没有任何作用,它仍会抛出&#34; name3&#34;对于所有的expId。
这些没有用:
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 :(得分: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];
});
});
}
答案 1 :(得分:0)
我猜想IIFE的使用和绑定在一起,在第一个答案中有点奇怪。最好选择其中一个。由于in the newest versions of the browsers bind
is way faster than an IIFE closure和let
关键字,我可能会建议bind
方式。
您的案例的类似示例可能如下;
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));
}
&#13;