普通计数器与阵列计数器通过功能

时间:2018-06-24 18:41:27

标签: javascript arrays node.js

您好,优秀的开发人员,

我正在编写一个节点应用程序,但是遇到了计数器问题,但这可能是纯粹的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调用。

我的问题是,counterarrcounter都在for loop之前声明了, 为什么arrcounter不能正确地counter“保持跟踪”呢?在这种情况下,对counter采取的正确方法是什么?

4 个答案:

答案 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>