Obsah fóra
PravidláRegistrovaťPrihlásenie




Odpovedať na tému [ Príspevkov: 9 ] 
AutorSpráva
Offline

Užívateľ
Užívateľ
setInterval("objekt.metoda",50)

Registrovaný: 05.09.09
Príspevky: 1141
Témy: 127
Bydlisko: Lehota pod ...
Príspevok NapísalOffline : 14.12.2011 13:14

Môže mi niekto znalý povedať, či taký zápis môže fungovať? Mne teda nefungoval, ale chcem mať istotu, že chyba nebola niekde inde. To volanie objektu mi asi neprejde, či?
Kód:
setInterval("objekt.metoda",50)


Offline

Čestný člen
Čestný člen
setInterval("objekt.metoda",50)

Registrovaný: 11.08.07
Príspevky: 4088
Témy: 34
Bydlisko: Brno
Príspevok NapísalOffline : 14.12.2011 13:25

Samozrejme, ze nie, pretoze ak ako prvy argument setIntervalu pouzijes retazec (co je inak velke zlo, uz ani neratam, kolkokrat som to spominal), ten obsah retazca je evalovany. A zapis
Kód:
objekt.metoda;

predsa neznamena volanie metody. Pouzi jeden z nasledovnych, prvy je silne doporucovany, druhy je zly, aj ked funguje:
Kód:
setInterval(objekt.metoda,50);
setInterval("objekt.metoda()",50);


Offline

Užívateľ
Užívateľ
setInterval("objekt.metoda",50)

Registrovaný: 05.09.09
Príspevky: 1141
Témy: 127
Bydlisko: Lehota pod ...
Príspevok Napísal autor témyOffline : 14.12.2011 13:42

Ja už neviem z kade to mám, že fcii. setInterval sa MUSÍ predávať funkcia ako reťazec. Aj na W3school to tak vidím. To že to prejde cez eval, by som vlastne čakal, a mohlo ma napadnúť, dať tam tie úvodzovky.

Ale teraz ma zaujíma, ako to, že ti ten prvý príklad funguje. Ty sám píšeš, že objekt.metoda nie je volaním metódy. No to je pravda... A ako teda vyhodnocuje ten zápis z prvého príkladu?

A z kade je to pravidlo, že sa to predáva ako reťazec???


Offline

Čestný člen
Čestný člen
setInterval("objekt.metoda",50)

Registrovaný: 11.08.07
Príspevky: 4088
Témy: 34
Bydlisko: Brno
Príspevok NapísalOffline : 14.12.2011 14:13

W3schools je zbierka bludov, hned si to vyhod zo studijnych materialov.
Ten prvy priklad funguje tak, ze ak predas setIntervalu referenciu na funkciu, tak ono to tu funkciu zavola.


Offline

Užívateľ
Užívateľ
setInterval("objekt.metoda",50)

Registrovaný: 05.09.09
Príspevky: 1141
Témy: 127
Bydlisko: Lehota pod ...
Príspevok Napísal autor témyOffline : 14.12.2011 14:48

Takže to rozlišuje či dostane ako argument premennú(funkciu), alebo reťazec, ak som to správne pochopil.

Edit:
Či čo sa to tam vlastne deje? Alebo tú premennú(funkciu) zobere a prevedie ju na reťazec a následne ju prejde cez eval???


Offline

Čestný člen
Čestný člen
setInterval("objekt.metoda",50)

Registrovaný: 11.08.07
Príspevky: 4088
Témy: 34
Bydlisko: Brno
Príspevok NapísalOffline : 14.12.2011 15:31

camo píše:
Takže to rozlišuje či dostane ako argument premennú(funkciu), alebo reťazec, ak som to správne pochopil.
Spravne. Pricom tie rozdiely su este vacsie, ako sa zda na prvy pohlad; ak pouzijes retazec, kod v nom sa vykonava v globalnom scope, aha ->
Kód:
var n = 1;
(function()
{
   var n = 2;
   setTimeout(function()
   {
      alert(n);
   }, 1);
})();
Toto ti vyhodi 2, ale keby si si ten prvy argument prepisal na "alert(n);" aj s uvodzovkami, uz bude vysledok 1.


Offline

Užívateľ
Užívateľ
setInterval("objekt.metoda",50)

Registrovaný: 05.09.09
Príspevky: 1141
Témy: 127
Bydlisko: Lehota pod ...
Príspevok Napísal autor témyOffline : 14.12.2011 15:36

No mám dosť... :shock:

Je v tom nejaká logika s tými scopmi?


Offline

Čestný člen
Čestný člen
setInterval("objekt.metoda",50)

Registrovaný: 11.08.07
Príspevky: 4088
Témy: 34
Bydlisko: Brno
Príspevok NapísalOffline : 14.12.2011 16:46

Samozrejme, ze je. Kazda funkcia vytvara scope, a jednotlive scopy (ako sa to povie po slovensky? Rozsahy platnosti?) su do seba vnorene presne tak, ako vnaras funkcie. Cize majme nieco taketo:
Kód:
function e() {
   var p = 3.14;
   function f() {
      var n = 42;
      //miesto X
   }
   function g() {
   }
   // miesto Y
}
function h() {
}
A taky ten strom pre scopy vyzera nejak takto
Kód:
global
  |__ e()
  |  |__ p = 3.14
  |  |__ f()
  |  |   |__ n = 42
  |  |   |__ [X]
  |  |__ g()
  |  |__ [Y]
  |__ h()
No a pravidlo je, ze ked si raz na nejakom mieste v tom strome, tak "vidis" vsetko, co je na tvojej vetve (to su tie vertikalne ciary) a plus vsetko na vetvach v hierarchii vyssie, cize po tom strome mozes chodit iba hore-dole a dolava. To znamena, ze ak som v mieste X (oznacil som ho aj v kode, aj v tom strome), mam pristup k premennym n, p, k funkciam f (vidis? Som vnutri funkcie a zaroven k jej objektu mam pristup, samozrejme), g, e aj h. Ale ked som v mieste Y, nemozem uz siahat na premennu n, pretoze by som musel vojst do scopu f-ka.
V Javascripte je taka skvela ficura, ze jednotlive scopy si pamataju, ako ten strom z ich pohladu vyzeral, pricom v skutocnosti uz nemusi existovat vetva niekde vyssie. Majme ten kod, ktory som pisal v minulom prispevku, s tym alertovanim n-ka, len ho prepisem, nech su tie funkcie pomenovane.
Kód:
var n = 1;
(function F()
{
   var n = 2;
   setTimeout(function G()
   {
      alert(n);
   }, 1);
})();
Strom teda vyzera takto:
Kód:
global
  |__ n = 1
  |__ F()
     |__ n = 2
     |__ G()
No a teraz, kedze setTimeout bezi asynchronne (co znamena tolko, ze nasledujuci kod necaka, kym sa ten setTimeout vykona), takze v case, ked G bezi, uz F vlastne nema preco existovat - vsetok kod v nej bol vykonany a keby som ju nepomenoval (tzn. ze by na nu neexistovala referencia), nema preco ani byt v pamati. A tu prave prichadza ta vyhoda, ze funkcia G si pamata, ze na svojej vetve mala to n rovne dvom. Kdezto keby miesto Gcka bol retazec, on si svoj scope (svoju vetvu) nevytvori a kedze bezi asynchronne, nema sa uz dovnutra vetvy Fka ako dostat a uvidi len to, co je na globalnej vetve, teda n rovno jednej.
Kde sa toto este vyuziva? Pozri na nasledovny kod:
Kód:
<ul>
   <li>List item
   <li>List item
   <li>List item
</ul>
<script>
for (var c = document.getElementsByTagName('li'), e, i = 0; e = c[i]; i++)
{
   e.onclick = function()
   {
      alert('Polozka cislo ' + i);
   };
}
</script>
V skratke cyklom for to prejde vsetky <li> a kazdemu prideli takyto onclick. No ale problem je, ze keby si si skusil poklikat, vsade ti to vyhodi 3. To preto, ze i sa dostalo postupne na hodnotu 3 a dane onclick handlery vidia akurat to jedno i. Preto pozri, akym sposobom tam pridam closure (to je anonymna funkcia, ktora samozrejme vytvori scope):
Kód:
for (var c = document.getElementsByTagName('li'), e, i = 0; e = c[i]; i++)
{
   (function()
   {
      var j = i;
      e.onclick = function()
      {
         alert('Polozka cislo ' + j);
      };
   })();
}
Tentokrat kazdy jeden onclick handler lezi vo vlastnom scope, ktory vznikol vtedy, ked premenna i mala este hodnotu taku, ako by sme si predstavovali.


Offline

Užívateľ
Užívateľ
setInterval("objekt.metoda",50)

Registrovaný: 05.09.09
Príspevky: 1141
Témy: 127
Bydlisko: Lehota pod ...
Príspevok Napísal autor témyOffline : 14.12.2011 19:41

To je celkom zaujímavé, aj keď neviem či by som sa to odvážil použiť(radšej si hodnoty takých premenných niekde ukladám). Vyzerá to tak, že keby to takto nebolo, tak by to hádzalo chyby, ak by sa daný handler napríklad odkazoval na už neexistujúcu premennú. Ja som bol v tom, že po vykonaní funkcie teda aj tej, čo priraďuje handlery, prehliadač "po sebe pozametá" a zruší tie dočasné/privátne premenné.

No dík za prednášku. Kedy bude ďalšia? Alebo mám najprv pripraviť podklady? ;)


Odpovedať na tému [ Príspevkov: 9 ] 


Nemôžete zakladať nové témy v tomto fóre
Nemôžete odpovedať na témy v tomto fóre
Nemôžete upravovať svoje príspevky v tomto fóre
Nemôžete mazať svoje príspevky v tomto fóre

Skočiť na:  

Powered by phpBB Jarvis © 2005 - 2024 PCforum, webhosting by WebSupport, secured by GeoTrust, edited by JanoF
Ako väčšina webových stránok aj my používame cookies. Zotrvaním na webovej stránke súhlasíte, že ich môžeme používať.
Všeobecné podmienky, spracovanie osobných údajov a pravidlá fóra