为什么拼接方法有这种奇怪的行为?

时间:2012-09-17 14:12:22

标签: javascript angularjs

在我的应用程序中,我需要从数组中删除一个元素。但是我是JS的新手。我搜索了网络,每篇博文都在谈论splice()方法。所以我考虑使用它,但它有一个非常奇怪的行为。

这是我发现的帖子: http://www.w3schools.com/jsref/jsref_splice.asp http://viralpatel.net/blogs/javascript-array-remove-element-js-array-delete-element/

这是我的测试:

it("should delete all elements in array", function () {
    var ary = new Array();

    for (i = 0; i < 10; i++) {
        ary[i] = Math.random();
    }

    expect(ary.length).toBe(10);

    for (i = 0; i < 10; i++) {
        ary.splice(i, 1);
    }

    expect(ary.length).toBe(0);

});

以下是测试的结果:

  Firefox 15.0.1 Linux: Run 7 tests (Passed: 6; Fails: 1; Errors 0) (44.00 ms)
    should delete all elements in array failed (5.00 ms): Error: Expected 5 to be 0.

我使用角度JS。

非常感谢您的回复。这是另一个没有通过的测试:

var ary = new Array();

        ary = ['a', 'b', 'c', 'd'];

        ary.splice(0, 1);

        ary.splice(1, 1);

        ary.splice(2, 1);

        ary.splice(3, 1);

        expect(ary.length).toBe(0);

Firefox 15.0.1 Linux: Run 7 tests (Passed: 6; Fails: 1; Errors 0) (49.00 ms)
    Posting server policy.should delete all elements in array failed (5.00 ms): Error: Expected 2 to be 0.

作为@Matteo Tassinari建议这应该删除所有元素吗?

5 个答案:

答案 0 :(得分:3)

原因很简单:每个新的splice你的数组都会变短:

var arr = [1, 2, 3];
arr.splice(0, 1);
console.log(arr[0]); // 2
console.log(arr[2]); // undefined
console.log(arr.length); // 2

在代码splice的第二个循环中,您的阵列只会改变五次。但是第六次(当i等于5时),arr.splice(5, 1)操作将有效地导致无操作,因为你的数组将只有5个元素。

您可以像在@MatteoTassinari回答中那样修复它,或者只使用splice(0, 1)(或仅shift())代替splice(i, 1)

答案 1 :(得分:1)

尝试替换它:

for (i = 0; i < 10; i++) {
    ary.splice(i, 1);
}

用这个:

for (i = 0; i < 10; i++) {
    ary.splice(0, 1);
}

删除特定元素,例如:

ary = ['a', 'b', 'c', 'd'];

如果你想删除'c',只需执行:

ary.splice(2, 1);

实际上,2这里是必须删除的元素的从0开始的索引。

答案 2 :(得分:1)

要使其正常工作,您需要始终删除索引0处的元素。否则,在8元素之后,您将执行ary.splice(8, 1),并且在此时,数组只剩下2个元素,arr.splice(8, 1)赢了“ t删除any,因为索引8不再存在。

for (i = 0; i < 10; i++) {
    ary.splice(0, 1);
}

答案 3 :(得分:1)

当您从数组中拼接元素时,数组会变短。因此,循环的最后5次迭代尝试拼接不存在的元素。

如果您将代码更改为:

for (i = 0; i < 10; i++) {
    ary.splice(0, 1);
}

它可以按照你的单元测试的预期工作。

答案 4 :(得分:1)

当你splice你的数组时,(并删除一个数组元素),你也可以&#34;移动&#34;所有其他数组元素前进。

在任何拼接之前考虑这个数组:

ary = [0,1,2,3,4,5,6,7,8,9]

ary.splice(0,1)之后,它看起来像这样:

ary = [1,2,3,4,5,6,7,8,9],

请注意,第0个索引(ary[0])现在是1,当您继续执行ary.splice(1, 1)时,您不会删除第一个元素,但实际上删除了第二个元素(在这种情况下为2

我知道这不是你要求的,而是一种更有效的方式来重置&#34;你的数组要做以下两件事之一:

ary.length = 0;
// or:
ary = [];