Generalnie problemy z inicjacją zmiennych w JavaScript pojawiają się gdy zaczynamy tworzyć równolegle wykonywane fragmenty kodu, czyli używamy window.setTimeout() oraz window.setInterval(). Szkopuł tkwi w tym, że zmienna utworzona bez użycia "var" zachowuje się jak zmienna statyczna, a dopiero dodanie wspomnianego słówka powoduje, że będzie się ona zachowywać jak normalna zmienna lokalna.
Może jednak pokażę na przykładzie o co mi chodzi :) Przykład będzie trywialny, ot mamy dwa guziki z liczbami, z których pierwszy po kliknięciu ma dodawać "0.1" co 1/10 sekundy, a drugi ma "0.1" odejmować. Oczywiście te 0.1 nie mogą być na sztywno zapisane wewnątrz funkcji.
<script type="text/javascript"> function __countNoVar(node, finalValue) { delta = finalValue - Number(node.innerHTML); delta = Number(Number(delta / 10 ).toFixed(1)); var intervalIdent = self.setInterval(function(){ node.innerHTML = (Number(node.innerHTML)+delta).toFixed(1); },100); } </script> <button onclick="__countNoVar(this, 1);">0</button> <button onclick="__countNoVar(this, -1);">0</button>Dodaje: Odejmuje:
Jak widać jeśli pojedynczo wciśniemy guziki to działają bez problemu, ale w momencie wciśnięcia drugiego buttona nagle również pierwszy zaczyna liczyć w tym samym "kierunku" co ostatnio wciśnięty. Dzieje się tak właśnie z powodu braku "var" przed deklaracją zmiennej "delta", czego wynikiem jest używanie nowej wartości tej zmiennej tak w ostatnio utworzonym "wątku" jak i we wszystkich poprzednich utworzonych za pomocą funkcji "__countNoVar".
Wersja z "varem", która w wyglądzie różni się dosłownie 3 literami działa już jednak poprawnie:
<script type="text/javascript"> function __countWithVar(node, finalValue) { var delta = finalValue - Number(node.innerHTML); delta = Number(Number(delta / 10 ).toFixed(1)); var intervalIdent = self.setInterval(function(){ node.innerHTML = (Number(node.innerHTML)+delta).toFixed(1); },100); } </script> <button onclick="__countWithVar(this, 1);">0</button> <button onclick="__countWithVar(this, -1);">0</button>Dodaje: Odejmuje:
http://download.oracle.com/docs/cd/E19957-01/816-6408-10/stmt.htm#1066604
OdpowiedzUsuńNikt nie czyta manuali, przez co PHP, JS i inne 'łatwe' języki mają opinie złych, topornych, wolnych etc.
Sytuacji jednak zapewne nie poprawia fakt, że manuale są tak przejrzyste i czytelne, że hej :P
OdpowiedzUsuńPoza tym nie nazwałbym PHP czy JS łatwymi. One po prostu są zubożone względem pierwowzorów.