2016-09-20 7 views
1

Это связано с некоторыми угловыми, но я думаю, что это, в основном, вопрос с вопросом о 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 всегда равно числу последнего индекса, который был вызван (Ex: Если у меня есть 3 метки, соответствующие моей директивы, и печать console.log(current_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_index в настоящее время передается в качестве объекта, и a это передается как примитив, но оба возвращают number, когда я делаю функцию typeof. Что тут происходит?

+1

Он передается по значению во всех случаях, которые вы показываете, но из-за видимости вы получаете неправильное поведение. В версии с переменной 'a' действительно ли вы объявляете' a'variable, как показано в строке после и в той же области, что и декларация 'current_index'? (См. Также [этот вопрос] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example).) – nnnnnn

+0

thats scope выпуск. вам нужно обернуть его закрытием – YOU

+0

Мне удалось ответить на ответ в связанном вопросе, но я до сих пор не понимаю, зачем вводить новую переменную, только одну строку ниже, было бы иначе. Я бы подумал, что они будут иметь одинаковый охват, и новая переменная также будет неправильной. – apdm

ответ

1

Это может ввести в заблуждение. Но помните, что вы не передаете current_index здесь, вы определяете функцию, которая имеет замыкание, и через это закрытие имеет доступ к переменной current_index в родительской области.

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

Так что, если вы измените значение CURRENT_INDEX, независимо current_index, когда что анонимная функция вы создали там выполняет, это то, что будет передано галочкой().

Это одна из причин, по которой создание функций внутри циклов for является опасным. Вам нужно будет либо использовать сразу вызываемую функцию, которая принимает текущий индекс в качестве аргумента, а возвращает функцию, которую вы хотите выполнить .on. Или вы можете связать функцию, которую вы передаете:

.on("start", function(boundIndex){ 
    tick(boundIndex); // now the value at the time of binding is bound 
}.bind(null, current_index); 
Смежные вопросы