使用array.splice时出现undefined不是一个函数的错误提示。

3
我想从数组中移除一些元素,并使用splice功能同时返回这些值。请参见下面的javascript代码:
var blocksUsed = allNumbers.splice(0,3);

当尝试运行这一行代码(与整个函数一起),会出现以下错误:

Uncaught TypeError: undefined is not a function

我花了相当长的时间检查函数中是否存在排版错误,但似乎没有发现任何问题。我还发现JQuery经常是造成此类问题的罪魁祸首,但我并未使用JQuery。
该数组是通过对另一个数组进行洗牌操作创建的(shuffle函数不是我写的):
function shuffle(o){
    for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
    return o;
};

然后我会用以下方式使用它:

var allNumbers = shuffle(blocks);

我尝试记录所有数字,这一步骤已经正确地完成。数组正确地进行了洗牌。然而,在对其进行splice时,会出现相同的错误。请注意,我是在for循环内执行splice操作的。以下是代码。
for (var i = 0; i < 4; i++){

    // Get a block of 3 blocks.
    var blocksUsed = allNumbers.splice(0,3); // This line gives the error.

    // Determine the color used for these blocks and remove it so that it doesn't get drawn again.
    var colorIndex = randomIntFromInterval(0,i);
    var colorUsed = otherColors[colorIndex];
    if(otherColors.indexOf(colorUsed) > -1){
        otherColors.splice(colorIndex, 1);
    }

    // For each block, set the color.
    for(var j = 0; j < 3; j++){
        blocksUsed[j].className = "block " + colorUsed;
    }
}

为什么我不能在这个数组上使用splice?如果需要,我可以提供整个函数。您可以参考codepen

因为有以下注释:

allNumbers是一个打乱顺序的数组,包含按以下方式接收到的元素:

var blocks = document.getElementsByClassName('block');

这是一个包含 div 元素的数组。 - Matthijs
2
blocks 不是一个数组,它是一个 NodeListallNumbers 也是如此。 - Barmar
"for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);" 这是我最近看到的最糟糕的代码行。 - spender
2个回答

5
var blocks = document.getElementsByClassName('block');

那不是一个数组。它只是类似于数组。你需要将其转换为一个数组。

var elems = document.getElementsByClassName('block');
var blocks = Array.prototype.slice.call( elems, 0 );

5

blocks 不是一个 Array。它是一个 NodeList,因此您需要使用 [].slice.call,它将接受类似数组的结构 blocks 并返回预期的结果。

var blocksArr = [].slice.call(blocks, 0); 
var blocksUSed = blocksArr.splice(0, 3);

不要使用 splice!尝试修改 nodelist 会引发错误! - Bergi
@Bergi从未听说过这个。有链接吗?无论如何,我已经改变了它。 - Amit Joki
我刚刚尝试了一下,结果出现了异常 Failed to update length。这是有道理的,因为length被规定为只读 - Bergi
@Matthijs:是的,现在可以了。这个版本不行。 - Bergi
@Matthijs,我对+15很满意,但也许是epascarello第一次回答正确,更应该得到它。Bergi,谢谢你。我不知道。 - Amit Joki
@AmitJoki:好的,没问题;) - Matthijs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接