Javascript 为什么这个原语变量是通过引用而不是通过值传递给函数的?

Javascript 为什么这个原语变量是通过引用而不是通过值传递给函数的?,javascript,angularjs,Javascript,Angularjs,这涉及一些角度,但我认为这主要是一个纯javascript范围的问题。我有一个指令,在我的页面上用ng repeat调用了几次。第一次调用时,我将变量current_index设置为等于单元页面上标记的索引号,如下所示: var current_index = scope.$eval(attrs.index); 然后我将它传递给一个延迟半秒的函数 g.append("g") .transition() .duration(500) //Half second delay

这涉及一些角度,但我认为这主要是一个纯javascript范围的问题。我有一个指令,在我的页面上用
ng repeat
调用了几次。第一次调用时,我将变量
current_index
设置为等于单元页面上标记的索引号,如下所示:

var current_index = scope.$eval(attrs.index);
然后我将它传递给一个延迟半秒的函数

    g.append("g")
    .transition()
    .duration(500) //Half second delay
    .on("start", function(){
      tick(current_index);  //Passing the current_index variable
    });
但是,当为标记的每个实例调用此函数时,
current\u index
始终等于调用的最后一个索引的数目(例如:如果我有3个标记对应于我的指令,并打印
console.log(current\u index);
在我的延迟函数中,它将打印
2
3次,而不是
0,1,2

function tick(index){
      console.log(index);
    }
 // Prints 2, 2, 2
但是,如果我引入一个新变量,
a
,并将其设置为等于
current_index
,然后将其传递到函数中,它将按预期工作

var current_index = scope.$eval(attrs.index);
var a = current_index

g.append("g")
.transition()
.duration(500) //Half second delay
.on("start", function(){
  tick(a);  //Passing the a variable
});


function tick(index){
      console.log(index);
    }
 // Prints 0, 1, 2

看起来,
current\u index
是作为对象传递的,而
a
是作为原语传递的,但是当我执行
typeof
函数时,两者都返回
number
。这是怎么回事?

这可能会让人困惑。但是请记住,这里不是传递current\u index,而是定义了一个函数,它拥有一个闭包,并通过该闭包访问父范围中的变量current_索引

.on("start", function(){
  tick(current_index); // you have access to this because of the closure
});
因此,如果您更改当前_index的值,那么当您在那里创建的匿名函数执行时,无论当前_index是什么,都将传递给tick()

这就是为什么在for循环中创建函数是危险的原因之一。您需要使用一个立即调用的函数,该函数将当前索引作为参数,并返回所需的函数。on执行。或者您可以绑定正在传递的函数:

.on("start", function(boundIndex){
  tick(boundIndex); // now the value at the time of binding is bound
}.bind(null, current_index);

在您显示的所有情况下,它都是按值传递的,但由于范围的原因,您得到了错误的行为。在带有
a
变量的版本中,您是否真的声明了
a
变量,如后一行所示,并且声明的范围与
当前索引
声明的范围相同?(另请参见。)这就是范围问题。你需要用closure把它包起来。我能够按照链接问题中的答案进行操作,但我仍然不明白为什么引入一个新变量(下面只有一行)会有任何不同。我认为它们具有相同的范围,新变量也将是错误的。哦,这两个变量确实是在后面声明的彼此喜欢那样吗?在这种情况下,我无法解释您看到的行为,除非有其他代码更新
current\u index
变量。如果
current\u index
是一个原始值(如数字),那么,将其指定给
a
并使用
a
而不是
current_index
的唯一原因是,在您实际使用该值之前,如果其他代码正在更改
current_index
。否则,这两个变量包含相同的值,并且在相同的范围内。我们可能会ed希望在代码中看到更大的上下文,以理解任何其他可能更复杂的情况。