我正试图在JS上构建一个非常简单的交互式电影播放器,只是为了好玩。 wireTo(x)通过在相同索引上预定义的持续时间触发每个场景。 (这是我的期望)
我创建了一个循环,并将 setTimeout 函数放入其中。它在每个duration属性上都没有问题地进行迭代,但是不能使用name属性处理(跳转到最后一个属性)。
var MoviePlayer = (function() {
function MoviePlayer(scenes) {
this.setSource(scenes);
}
MoviePlayer.prototype.setSource = function(_scenes) {
this.scenes = _scenes;
}
MoviePlayer.prototype.wireTo = function(number) {
var parts = this.scenes[number].parts;
for (var x in parts) {
var name = parts[x].name; // I think the problem starts here
setTimeout(function() {
alert(name);
}, parts[x].duration * x);
}
}
return MoviePlayer;
}());
// scenes configuration json
var scenes = [
{
ep: 1,
parts: [
{ name: "episode 1 p1", duration: 1000 },
{ name: "episode 1 p2", duration: 3000 }
],
next: 2
},
{
ep: 2,
parts: [
{ name: "episode 2 p1", duration: 1000 },
{ name: "episode 2 p2", duration: 1000 }
],
next: 3
}
];
// instantiation
let player = new MoviePlayer(scenes);
player.wireTo(0);
我的逻辑有什么问题。任何帮助将不胜感激。谢谢。
答案 0 :(得分:0)
由于var
的作用范围是该函数,因此您只有一个name
变量,可用于循环中的每个迭代。因此,您将继续覆盖该变量,并且当计时器最终关闭时,它们都将看到您用其覆盖的最后一个值。
最简单的解决方法是只使用let而不是var。 let的作用域是块而不是函数,因此每次通过for循环时,您将拥有一个具有自己绑定的新变量。
for (let x in parts) {
let name = parts[x].name;
setTimeout(function() {
alert(name);
}, parts[x].duration * x);
}