Jak przekazać wartość (nie referencję) zmiennej JS do funkcji? [duplikat]
To pytanie ma już odpowiedź tutaj:
Oto uproszczona wersja czegoś, co próbuję uruchomić:
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
}
Ale uważam, że każdy słuchacz używa wartości wyników.length (wartość po zakończeniu pętli for). Jak Mogę dodać słuchaczy takich, że każdy używa wartości i w momencie dodawania go, a nie odniesienia do i?
6 answers
W nowoczesnych przeglądarkach możesz użyć słów kluczowych let
lub const
, aby utworzyć zmienną o zasięgu blokowym:
for (let i = 0; i < results.length; i++) {
let marker = results[i];
google.maps.event.addListener(marker, 'click', () => change_selection(i));
}
W starszych przeglądarkach należy utworzyć osobny zakres, który zapisze zmienną w bieżącym stanie, przekazując ją jako parametr funkcji:
for (var i = 0; i < results.length; i++) {
(function (i) {
marker = results[i];
google.maps.event.addListener(marker, 'click', function() {
change_selection(i);
});
})(i);
}
Tworząc funkcję anonimową i wywołując ją ze zmienną jako pierwszym argumentem, przekazujesz wartość do funkcji i tworzysz zamknięcie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 10:27:04
Oprócz zamknięć, możesz użyć function.bind
:
google.maps.event.addListener(marker, 'click', change_selection.bind(null, i));
Przekazuje wartość i
in jako argument do funkcji po wywołaniu. ({[4] } jest do wiązania this
, którego w tym przypadku nie potrzebujesz.)
function.bind
został wprowadzony przez Prototype framework i został ustandaryzowany w ECMAScript Fifth Edition. Dopóki wszystkie przeglądarki nie obsługują go natywnie, możesz dodać własne function.bind
wsparcie za pomocą zamknięć:
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner,
args.length===0? arguments : arguments.length===0? args :
args.concat(Array.prototype.slice.call(arguments, 0))
);
};
};
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-02 22:19:35
Zamknięcia:
for (var i = 0, l= results.length; i < l; i++) {
marker = results[i];
(function(index){
google.maps.event.addListener(marker, 'click', function() {
change_selection(index);
});
})(i);
}
EDIT, 2013: Są one obecnie powszechnie określane jako IIFE
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-19 14:12:39
Kończysz z zamknięciem. Oto artykuł na temat zamknięć i jak z nimi pracować. Sprawdź przykład 5 na stronie; to scenariusz, z którym masz do czynienia.
EDIT: cztery lata później link nie działa. Głównym powodem powyższego problemu jest to, że pętla for
tworzy zamknięcia(konkretnie na marker = results[i]
). Ponieważ {[2] } jest przekazywane do addEventListener
, widzisz efekt uboczny zamknięcia: współdzielone "środowisko" jest aktualizowane z każdą iteracją pętli, zanim w końcu zostanie "zapisany" poprzez zamknięcie Po ostatecznej iteracji. MDN wyjaśnia to bardzo dobrze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-22 21:12:45
for (var i = 0; i < results.length; i++) {
marker = results[i];
google.maps.event.addListener(marker, 'click', (function(i) {
return function(){
change_selection(i);
}
})(i));
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-17 15:45:58
Myślę, że możemy zdefiniować zmienną tymczasową do przechowywania wartości i.
for (var i = 0; i < results.length; i++) {
var marker = results[i];
var j = i;
google.maps.event.addListener(marker, 'click', function() {
change_selection(j);
});
}
Nie testowałem go jednak.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-06 17:20:56