JavaScript(JS)函数数组相等是否作为指针?

JavaScript (JS) function array equality works as pointer? How to just use the variables?

我正在创建一个代码,需要在其中使用全局范围中的一些变量,当我将local=global设置为global时,我注意到我在本地范围中所做的更改正在被修改为全局范围。

这是我所说的一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
global = [];
load_global();
use_global();

function load_global() {
  for (i = 0; i < 10; i++) {
    global.push(i);
  }
}

function use_global() {
  local = [];
  local = global;
  for (i = 0; i < 5; i++) {
    global.push("x");
  }
  console.log(local);
}

JSB实例

是否有一种方法可以使用全局数组的值,但不更改它?


在JavaScript中,和许多其他语言一样,您只处理对象的引用。这也意味着"在"数组中的对象也可能需要被复制。基于使用Array.slice()的答案很好,但它不会对数组中的项进行深度复制(意味着数组中的对象元素也会被复制,因此更改本地对象的状态不会影响全局对象)。

一个非常简单(但可能不是非常有效)的解决方案可以是对数组进行序列化和反序列化。前任:

1
var newObj = JSON.parse(JSON.stringify(obj));

注意,使用JSON不允许处理函数。这里有一个使用这种技术的答案。

编辑

为了允许深度复制,您还可以像dmaster建议的那样迭代对象的属性,但是您应该使用一些递归的kine。我从So中的这个答案中取了这个例子。

1
2
3
4
5
6
7
8
9
function clone(destination, source) {
    for (var property in source) {
        if (typeof source[property] ==="object" && source[property] !== null && destination[property]) {
            clone(destination[property], source[property]);
        } else {
            destination[property] = source[property];
        }
    }
}


除了老派的Array#slice外,您还可以使用es6方法Array.from,它是为这种情况而设计的:

1
var local = Array.from(global)

此方法可用于类似数组的对象或任何不具有slice方法的可Iterable值。你可以说是Array.prototype.slice.call()。哦,你说得对,但这不是很烦人吗?

此外,还可以将映射函数传递给它。例如:

1
Array.from('asdf', c => c.toUpperCase())  // ["A","S","D","F"]

与ES5样式相比,您可以看到ES6有多整洁:

1
Array.prototype.slice.call('asdf').map(function(c){return c.toUpperCase()})

阅读MDN文档了解更多信息。

另一方面,目前还没有广泛支持该方法,您需要babel或polyfill。但是ES6是未来的,最终它将得到所有主要浏览器的完全支持。


您需要将数组克隆到局部变量中。例如,您可以使用sliceconcat来实现这一点。

要将clone添加到javascript数组中,可以使用

1
2
3
Array.prototype.clone = function() {
    return this.slice(0);
};

然后

1
var localArray = globalArray.clone();

这里还要检查这个问题javascript复制数组切片的最快方法vs for循环


您可以尝试复制全局数组

1
local = global.slice()

顺便说一下,您可能希望使用var关键字使该数组成为本地的。如果没有它,"本地"数组将可以从函数外部访问