当我特别说我不希望它通过引用传递数组

Array being passed by reference when I specifically say I don't want it to

我正在编写一个函数来计算矩阵的行列式。算法本身是无关紧要的,但是如果你有兴趣,可以在this page.

的底部找到它
function det(matrix) {
    var dim = validate(matrix); // this function checks if it's an actual matrix and returns its dimensions as [rows, columns]
    if(dim && dim[0] === dim[1]) {
        var ord = dim[0];
        if(ord === 2) {
            return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy
        } else {
            var r = 0;
            for(var i = 0; i < ord; i++) { // using the first row
                var elem = matrix[i][0],
                    mod = Math.pow(-1, i + 2);
                    minor = matrix.slice(0);
                console.log(ord);
                minor.splice(i, 1); // remove the ith column
                for(var j = 0; j < ord - 1; j++) {
                    minor[j].splice(0, 1); // remove the first row
                }
                r += elem * mod * det(minor);
            }
            return r;
        }
    } else {
        return false;
    }
}

有一个问题:我有一个数组 matrix,我想一直表示原始矩阵,即我不想修改它。当我复制它时,我写 var minor = matrix.slice(0); 来创建一个新数组并停止 matrix 通过引用传递。当然这意味着 minor 是一个单独的对象?显然不是。我没有在 else 分支的任何进一步位置引用 matrix,但是,在某个地方,它被修改了。通过 bruteforceesque console.logging,我将范围缩小到这一行:

minor[j].splice(0, 1); // remove the first row

但是为什么呢?为什么这一行绝不会引用 matrix 最终会改变它的值?当然它应该只改变 minor 的值吗?我该怎么做才能解决这个问题?

Javascript 数组是一维的——你的矩阵是数组的数组。当您调用 slice 时,您创建了一个浅拷贝。也就是说,您正在创建一个新的外部数组,其中包含完全相同的内部数组。您想制作一个深拷贝,同时创建新的内部数组。

function cloneMatrix (matrix) {
    return matrix.map(function(sub) { return sub.slice(0); });
}

基于这条线:

return matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]; // easy

我推断数组中每一项的值是另一个数组。

所以:

  • matrix 是一个值为 "Reference to some array"
  • 的变量
  • minor 是一个值为 "Reference to an array that is a duplicate of the first array"
  • 的变量
  • matrix[0] 是一个值 "Reference to another array"
  • minor[0] 是一个变量,它是 matrix[0] 的副本,因此它是对同一数组的引用。 (同样适用于彼此的索引)。

您需要复制 所有 个数组。