Javascript 使用shift()和push()循环数组值与使用计数器变量相比,最好的方法是什么?

Javascript 使用shift()和push()循环数组值与使用计数器变量相比,最好的方法是什么?,javascript,Javascript,我在动画帧数组中循环浏览一组图像。共有7个图像,从1到7循环完成动画。我需要这个动画无限循环,但我想知道以下哪种方法是最好的: 通过修改数组进行循环 /* Pull image from start of array. */ var image = frames.shift(); /* Process image. */ ... /* Add image back to end of array. */ frames.push(image ); 使用计数器变量循环 /* Pull image

我在动画帧数组中循环浏览一组图像。共有7个图像,从1到7循环完成动画。我需要这个动画无限循环,但我想知道以下哪种方法是最好的:

通过修改数组进行循环

/* Pull image from start of array. */
var image = frames.shift();
/* Process image. */
...
/* Add image back to end of array. */
frames.push(image );
使用计数器变量循环

/* Pull image by counter offset. */
var image = frames[counter];
/* Process image. */
...
/* Increment or reset counter value. */
counter + 1 === frames.length ? counter = 0 : counter = counter + 1;

我为什么选择一个而不是另一个?或者,有更好的方法吗?

修改数组将比简单地使用变量跟踪您在数组中的位置更昂贵。如果无限循环,更好的方法似乎是使用
while
循环(而不是使用
for
循环重置内部计数器):

但是,如果您的目标确实是让动画在每次给定间隔结束时无限期地继续,那么循环根本就不理想。改用


其中,
time\u运行间隔
是再次调用函数之前应经过的时间。

一种可能性是放弃数组并使用链表

使每个帧成为指向下一个对象的对象。最后一个指向第一个。然后,您所需要做的就是引用下一个对象

var curr = first; // reference to first frame object

setInterval(function() {

    // process image
    curr.image.doSomething();

    // proceed to next
    curr = curr.next;

}, 1000);
没有柜台可以这样乱搞


设置链表通常非常简单,只需对设置数组的当前代码稍加修改即可完成

var first = new Frame(); // This is your entry point
var current = first;        // This holds the current frame during setup

for (var i = 0; i < totalFrames; i++) {
    current.next = new Frame();   // Make the current reference a new frame
    current = current.next;          // Make the new frame current
}

current.next = first; // circular reference back to the first.

function Frame() {
    // set up this frame
}

或者,我认为也可以使用循环链表。要将对象数组转换为循环链表,请执行以下操作:

frames.forEach(function(elem, index) { 
    elem.next = frames[index + 1] || frames[0];
});
现在你可以这样做:

setInterval(function() {
    frame = frame.next;
    ....
}, delay);

我会使用
计数器%frames.length
。数组操作相当繁重,
shift
会导致重新枚举数组项的索引,而属性查找非常便宜。FWIW,可以使用模运算符循环计数器:
counter=(counter+1)%frames.length编辑:法布里西奥说的;)啊,我根本没有考虑模数。多么简单!如果你觉得自己很花哨,你可以把它们绕一圈,然后说
image.next=frames[(i+1)%frames.length]。然后在你的动画中,只需抓住你处理过的最后一张图像,然后说类似于
image=image.next并且再也不用担心数组或计数器了…:)拥有一个“动画帧数组”听起来不像是这样的
,而
循环将是正确的选择。无论如何,使用计数器肯定是正确的选择。@Felix True,我想我的意思是,与在内部修改计数器的for循环相反。我将进行更新。作为说明,我实际上正在为此使用
setInterval
。:-)编辑:啊,你已经把它添加到你的答案中了。@James哦,好吧,不知怎的,我以为我在某处看到了“for loop”这个短语……我的错误。无论如何,使用变量,不要更改数组。:)
var first = new Frame(null); 
var current = first;

for (var i = 0; i < totalFrames; i++) {
    current = new Frame(current);
}

current.next = first;

function Frame(currFrame) {
    // link this frame to the given one
    if (currFrame)
        currFrame.next = this;

    // set up the rest of this frame
}
frames.forEach(function(elem, index) { 
    elem.next = frames[index + 1] || frames[0];
});
setInterval(function() {
    frame = frame.next;
    ....
}, delay);