如何确保变量不通过引用传递

时间:2016-03-10 12:49:10

标签: javascript scope pass-by-reference

我有这段代码:

A

如您所见,循环执行两次,因为splice正在修改数组calculateSum。我不知道的是它在功能范围之外引用A的原因。

第1个问题:不应该A有自己的范围而不是在其范围之外定义的JSON.parse吗?

2d问题:承认我不明白这是怎么可能的,什么是javascript中没有使用unset黑客的优雅解决方案(出于性能原因),外部图书馆?

4 个答案:

答案 0 :(得分:2)

在javascript中传递数组时,该数组的值是引用,这就是函数的A变量与外部作用域.slice();变量相同的原因。你必须克隆它才能打破引用。

克隆数组的简便方法是使用var B = A.slice();

{{1}}

答案 1 :(得分:2)

第1个问题:不应该计算Sum有自己的范围而不是在其范围之外定义的引用A?

Ans:calculateSum有自己的范围,它不在A定义的外部运行。它在A上运行,定义了参数。但是,因为在调用calculateSum时您正在传递数组实例A的引用,所以A都是对同一个Array实例的引用。

2d问题:承认我不明白这是怎么可能的,javascript中的优雅解决方案是什么,不使用JSON.parse黑客(出于性能原因),都不是外部库?

Ans:使用A.slice();克隆数组,然后将其传递给函数。

答案 2 :(得分:1)

  第一个问题:不应该计算太有自己的范围而不是   引用A是否在其范围之外定义?

是的,但是您将同一个对象传递给该范围,只是该引用不同。

  

2d问题:承认我不明白这是怎么可能的,是什么   一个优雅的javascript解决方案,不使用JSON.parse黑客   (出于性能原因),外部库都没有?

只需这样做

console.log( test(A.concat([])));

console.log( test(A.slice(0)));

这将创建一个新对象并传递给test方法。

答案 3 :(得分:1)

您可以使用多种方法复制Array,查看此jsperf以查看哪种方法更快。

var myArray = [1,2,3];
var myClone = clone( myArray );

function clone ( toClone ) {
    a = [];

    for ( i = toClone.length; i--; ) {
        a.push( toClone[i] );
    }

    return a;
}

似乎迭代速度最快,但请注意,如果数组中的元素为Objects,则不会复制,而是引用。

var myArray = [{},{},{}];
var myClone = clone( myArray );
myClone[0].foo = 'bar';
console.log( myArray[0].foo ); // 'bar'