有没有办法在函数调用中更改对对象的原始引用

Sha*_*dow 4 javascript

我在 JavaScript 中使用数组,想知道为什么我对数组所做的更改正确保存到 localStorage,但在函数调用之后没有反映在数组中。代码如下:

function removeFromList(array, arrayName, key) {
  array = array.filter(function(element) { return element.key !== key; });
  localStorage.setItem(arrayName, JSON.stringify(array));
}
Run Code Online (Sandbox Code Playgroud)

我做了一些谷歌搜索,通过一些旧帖子,发现数组是按值传递给函数的,也就是说,指向数组对象的数组变量是按值传递的,更改该副本并没有影响指向我的数组对象的原始变量。

我想出了以下代码作为解决方法:

function removeFromList(array, arrayName, key) {
  arrayTemp = array.filter(function(element) { return element.key !== key; });
  for(var i = 0; i < array.length; i++) {
    if (!arrayTemp.some(item => item.key === array[i].key)) {
      array.splice(i, 1);
    }
  }
  localStorage.setItem(arrayName, JSON.stringify(array));
}
Run Code Online (Sandbox Code Playgroud)

这解决了我的问题,数组的新内容同时显示在 localStorage 和原始变量指向的数组对象中。但是,我一直想知道最近是否有一些新方法引入到 JavaScript 中,或者我没有发现可以更好地实现预期结果的旧方法。

T.J*_*der 5

我做了一些谷歌搜索,通过一些旧帖子,发现数组是按值传递给函数的,也就是说,指向数组对象的数组变量是按值传递的,更改该副本并没有影响指向我的数组对象的原始变量。

非常正确。

有没有办法在函数调用中更改对对象的原始引用

不,JavaScript 仍然是一种纯粹的值传递语言。虽然我认为这可能会在某个时候发生变化,但在撰写本文时还没有发生(而且对我来说似乎真的不太可能)。如果这样做example(x),当x包含42(或阵列参考),仍然没有任何方式example伸手去改变x(〜43,或指代不同的阵列)。如果x引用一个可变对象(如数组),example可以修改该对象,但不能x引用一个全新的对象。

您的解决方法是修改现有数组。FWIW,通常最好返回新数组,因此调用者可以选择保留原始数组或使用新数组。例如:

function removeFromList(array, arrayName, key) {
    array = array.filter(function(element) { return element.key !== key; });
    localStorage.setItem(arrayName, JSON.stringify(array));
    return array;
}
Run Code Online (Sandbox Code Playgroud)

然后在使用时:

variableContainingArray = removeFromList(variableContainingArray, "nameInLocalStorage", 42);
Run Code Online (Sandbox Code Playgroud)

但是如果要就地更新,则不需要临时数组:

function removeFromList(array, arrayName, key) {
    // Looping backward we don't have to worry about the indexes when we remove an entry
    for (let i = array.length - 1; i >= 0; --i) {
        if (array[i].key === key) {
            array.splice(i, 1);
        }
    }
    localStorage.setItem(arrayName, JSON.stringify(array));
}
Run Code Online (Sandbox Code Playgroud)