Zagadka z JavaScript #1
Na dziś prosta zagadka z javascriptu. Deklarujemy obiekt, iterujemy po nim, przypisujemy event listenery (w jQuery, bo czemu nie?). Pytanie, jakie wartości wyświetli alert po klinięciu w kolejne zbindowane elementy?
PS. Szybka podpowiedź: zakładamy że kod wykona się poprawnie :)
Rozwiązanie:
See the Pen qEMLdO by Jakub Przyborowski (@przyb) on CodePen.
Dlaczego tak się dzieje? W JS nie mamy blokowych scope’ów. Oznacza to, że ciało pętli for nie dostaje zmiennej k na wyłączność. Kolejne iteracje pozostają więc w zasięgu tego samego domknięcia, a więc asynchronicznie wywoływany callback skorzysta z referencji do ostatniej wartości zmiennej. W naszym przypadku jest to „D”. Warto przy okazji poczytać o hoistingu, czyli wynoszeniu deklaracji zmiennych na początek scope’a.
Jak to obejść?
W przypadku pracy z tablicami, najprostszym sposobem jest wykorzystanie forEach dostępnej w prototypie Array. Niestety, język nie daje nam podobnej możliwości w pracy z obiektami. Pomocne są tu frameworki – możemy skorzystać z jQuery.each, angular.forEach czy choćby _.each. Jeśli chcemy osiągnąć ten sam efekt w czystym JS, możemy posłużyć się samowywołującą się lambdą, która stworzy nam nowy scope.
See the Pen xbamOG by Jakub Przyborowski (@przyb) on CodePen.