您好,优秀的开发人员,
我正在编写一个节点应用程序,但是遇到了计数器问题,但这可能是纯粹的JS问题。
我编写了此测试代码(而不是我的复杂问题),以便更清楚地说明问题。
var func2 = function(i,counter,arrcounter)
{
counter++;
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
var looptest = function(){
var counter = 0;
var arrcounter = [];
for (var i = 0 ; i<10 ; i++)
func2(i,counter,arrcounter);
}();
如您所见,我在for循环之前声明了var counter = 0
以及一个名为arrcounter
的数组,并将其传递给func2
,正在调用func2
每次迭代。
我得到了这个输出:
counter is 1
arrcounter 0
counter is 1
arrcounter 0,1
counter is 1
arrcounter 0,1,2
counter is 1
arrcounter 0,1,2,3
counter is 1
arrcounter 0,1,2,3,4
counter is 1
arrcounter 0,1,2,3,4,5
counter is 1
arrcounter 0,1,2,3,4,5,6
counter is 1
arrcounter 0,1,2,3,4,5,6,7
counter is 1
arrcounter 0,1,2,3,4,5,6,7,8
counter is 1
arrcounter 0,1,2,3,4,5,6,7,8,9
正如您在上面看到的,arrcounter
已“递增”校正(我不知道array.push的正确术语),但是整数counter
似乎在每次传递时均为0 func2调用。
我的问题是,counter
和arrcounter
都在for loop
之前声明了,
为什么arrcounter
不能正确地counter
“保持跟踪”呢?在这种情况下,对counter
采取的正确方法是什么?
答案 0 :(得分:1)
在Javascript中,原始类型按值传递。在您的情况下,计数器也会通过值传递,并且对它所做的更改将不会被反映回来。您将i
中的arrCounter array
推入正越来越大,这就是为什么arrCounter数组显示正确数据的原因。您的counter
变量不是global
变量,而是通过值传递给func2(),因此在func2()
中对其所做的更改不会被反映回来,这就是为什么始终将其传递仅为0。
如果您要增加计数器变量并将其值发送到Func2()
,它将开始显示正确的结果,请尝试以下操作:
var func2 = function(i,counter,arrcounter)
{
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
var looptest = function(){
var arrcounter = [];
var counter = 0;
for (var i = 0 ; i<10 ; i++)
func2(i,counter++,arrcounter);
}();
答案 1 :(得分:1)
var func2 = function(i,counter,arrcounter)
{
counter++;
console.log('counter is ' + counter);
arrcounter.push(i);
console.log('arrcounter ' + arrcounter);
}
此处,计数器参数首先已传递0。在javascript中,原始类型变量是通过value传递的,而不是通过引用传递的。在这里,变量计数器是数字类型,并且是原始类型。因此,当将其传递给func2时,将为func2创建一个局部变量计数器。因此,它将增加func2函数的本地计数器参数,而不是您在looptest函数中声明的计数器变量。
func2的本地计数器参数将增加为1,但您在looptest函数中声明的变量计数器将保持不变。因此,每次您要用0填充它时。
您可以尝试以下操作:
var looptest = function(){
var counter = 0;
var arrcounter = [];
for (var i = 0 ; i<10 ; i++)
{
counter++;
func2(i,counter,arrcounter);
}
}();
答案 2 :(得分:1)
在javascript变量中指向对象。这就是分配的作用-它们指向左手以引用右手。
当您将变量counter
传递到func2
时,参数指向对象,在这种情况下为数字。当func2
然后将变量counter
重新分配给新对象时,它将采用局部counter
并将其指向另一个数字对象。这对counter
中的变量looptest
没有影响。因此,for循环的每次迭代都会将0
传递到func2
。
传递数组时,它会传递对该数组的引用,因此func2
中的数组与loopiest'. In 'func2' you don't reassign the variable
arr , but rather alter the original object, so the changes are seen in the
looptest {{1}中的数组是同一对象} looptest`
在此示例中您可以清楚地看到这一点:
. So you see the changes reflected in
答案 3 :(得分:1)
更好地了解哪些参数是通过值传递的,哪些是通过引用传递的。
的参数
function
...原语类型通过值传递。
对象(和数组)通过引用传递。
var butImGlobal = 1;
var integerVar = 1;
var stringVar = 'change or not ?';
var array = [0,1];
var obj = {fruit: 'apple'};
function test(byvalInt, byvalTest, byrefArr, byrefObj){
byvalInt = 99999;
byvalTest = 'not change';
byrefArr.push('I\'m new!');
byrefObj.fruit = 'pineapple';
butImGlobal = 'my value is changed, and I can change my type too!';
}
document.getElementById('test').innerHTML = '<b>BEFORE</b><br/>integerVar = ' + integerVar + '<br/>stringVar = ' + stringVar + '<br/>array = ' + array.join(', ') + '<br/>obj.fruit = ' + obj.fruit + '</br>butImGlobal = ' + butImGlobal;
test(integerVar, stringVar, array, obj);
document.getElementById('test').innerHTML = document.getElementById('test').innerHTML +'<br/><br/><b>AFTER</b><br/>integerVar = ' + integerVar + '<br/>stringVar = ' + stringVar + '<br/>array = ' + array.join(', ') + '<br/>obj.fruit = ' + obj.fruit + '</br>butImGlobal = ' + butImGlobal;
<div id="test"></div>