为什么Array.prototype.pop()会影响其他数组?

时间:2015-08-07 14:37:20

标签: javascript arrays

我试图解决一个coderbyte挑战,我必须比较一个字符串中每个单词中的字母,然后用最重复的字母返回单词。 EX:" Hello World" - > "你好"

我仍在努力解决问题,但我遇到了一些涉及Array.prototype.pop()的奇怪行为;

这是我的代码:

function LetterCountI(str) { 

    str = str.split(" ");

    var largest = "";
    var letterCount = 0;

    for (var i = 0; i <str.length;i++) {
        letterCount = findMatches(str[i].split(""));  
    }

    function findMatches(array) {
        var letterCount = 0;
        while (array.length) {
            var letter = array.pop();
            var counter = 0;
            var arrayCopy = array;
            letterCount += compareRecursive(letter, arrayCopy, counter);
        }
        return letterCount;
    }

    function compareRecursive(letter, a, counter) {
        if (a.length === 0) {
            return counter;  
        }
        var n = a.pop();
        if (letter === n) {
            counter++;  
        }
        return compareRecursive(letter, a, counter);
    }
    return letterCount;     
}

发生的事情是我在compareRecursive函数中使用Array.prototype.pop()来返回数组的最后一个索引并使数组变小,这样我就可以遍历整个字符串。我在findMatches函数中调用compareRecursive。在调用compareRecursive之后,数组变量和arrayCopy变量被清空。根据我对范围的理解,compareRecursive函数应该有自己的数组副本,因为我将它作为参数传递,为什么Array.prototype.pop()会影响我的findMatches函数中的数组和arrayCopy变量?

当我更改行

var n = a.pop();

致:

var n = a[0];
a = a.slice(1);

findMatches函数中的数组和arrayCopy变量不受影响。为什么是这样?

1 个答案:

答案 0 :(得分:2)

pop()改变现有数组,删除最后一项。 slice()返回数组的浅表副本,而不是原始数组。

// pop
var foo = [1, 2, 3];
var three = foo.pop(); // "pops out" 3 from the array
// foo = [1, 2]
// three = 3;

// slice
var foo = [1, 2, 3];
var three = foo.slice(-1)[0]; // Creates new array with 3 inside (ie. [3])
// foo = [1, 2, 3];
// three = 3;

如果您想在不影响原始数组的情况下使用pop(因为pop非常方便),您可以使用slice创建数组的副本并将其弹出

var originalArray = [1, 2, 3];
var arrayClone = originalArray.slice();
var poppedItem = arrayClone.pop();
// originalArray = [1, 2, 3];
// arrayClone = [1, 2];
// poppedItem = 3;