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

时间:2016-09-20 03:13:19

标签: javascript angularjs

这涉及一些Angular,但我认为它主要是一个纯粹的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_index总是等于被调用的最后一个索引的数量(例如:如果我有3个标记对应于我的指令,并在我的函数中打印console.log(current_index);延迟时间,它将打印2 3次,而不是0, 1, 2

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

但是,如果我引入一个新变量a,并将其设置为等于current_index,并将THAT传递给函数,它将按预期工作。

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_index作为对象传递,a作为基元传递,但当我执行number函数时都返回typeof 。这是怎么回事?

1 个答案:

答案 0 :(得分:1)

这可能令人困惑。但是请记住,你没有在这里传递current_index,你正在定义一个函数,它有一个闭包,并且通过该闭包,可以访问父作用域中的变量current_index。

.on("start", function(){
  tick(current_index); // you have access to this because of the closure
});

因此,如果你改变current_index的值,那么当你在那里创建的匿名函数执行时,无论current_index是什么,那将会传递给tick()。

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

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