Autor Zpráva
xROAL
Profil
Zdravím, narazil som na dosť zvláštny problém. Mám následovný kód:
function objekt(){
  this.list = {};

  this.vytvorElement = function(){
    var el = document.createElement("div");
    el.id = "el1";
    document.body.appendChild(el);
    this.list.element = document.getElementById("el1");
  }

  this.citajElement = function(e){
    var el = this.list.element;
  }
}

var obj = new objekt;
obj.vytvorElement(); // div sa vytvori, vlozi sa do body, vsetko OK
obj.citajElement(); // Cannot read property "element" of undefined
Neviem z akého dôvodu dostávam tento error. Ak v konzole skúšam obj.list.element vráti mi to správny DIV, obj.list mi vráti objekt s prvkom element v ktorom je div#el1. Navyše to robí len táto jedna metóda, sú tam ešte aj iné metódy ktoré pristupujú k prvkom v this.list a tie s tým nemajú problém.

Neviete poradiť čím by toto mohlo byť spôsobené? Google mi v tomto moc neporadil.
Joker
Profil
xROAL:
Mně se to neděje, uvedený kód normálně proběhne.
Str4wberry
Profil
Který prohlížeč to dělá?

Pokud si ve funkci citajElement zmíněný element vrátím, normálně mi ho náísledný obj.citajElement vrátí.

Živá ukázka
xROAL
Profil
Robí mi to v Google Chrome a tu som vysekal časť reálneho kódu v ktorom sa to deje (i keď nevidím rozdiel oproti príkladu čo som napísal vyššie):
function player(){
  this.playlist = null;
  this.el = {};

  this.create = function(){
    if(!document.getElementById("player")){
      var main = document.createElement("div");
      main.id = "player";
      main.style.top = "-100%";
      document.body.appendChild(main);
      this.el.main = document.getElementById("player");

      var playlist = document.createElement("div");
      playlist.id = "playlist";
      playlist.style.left = "-25%";
      this.el.main.appendChild(playlist);
      this.el.playlist = document.getElementById("playlist");

      // ... kopa dalsich createElement...
    }
  }

  this.show = function(){
    if(this.el.main && this.el.main.style.top == "0%"){
      this.el.main.style.top = "-100%";
    }else{
      this.el.main.style.top = "0%";
    }
  }

  this.togglePlaylist = function(e){
    var playlist = this.el.playlist; // tu nastane chyba Cannot read property...
    var player = this.el.player;
    var button = e.target;
    if(playlist.style.left != "0%"){
      playlist.style.left = "0%";
      player.style.margin = "0 1% 0 26%";
      button.className = "hide";
    }else{
      playlist.style.left = "-25%"
      player.style.margin = "0 5%";
      button.className = "";
    }
  }
}
Po zavolaní create() nemá metóda show() problém s prístupom k this.el, togglePlaylist() však hlási že this.el je undefined.
_es
Profil
xROAL:
togglePlaylist() však hlási že this.el je undefined.
A akým spôsobom je uvedená metóda volaná? Od toho závisí, čo je vtedy this. Možno je this.e undefined preto, že je this niečo iné, než si myslíš a chyba je (aj) inde, ako v uvedenom kóde. Asi si celkom neporozumel platnosti premenných a ako funguje this. Napríklad, v kóde v [#1] nemajú riadky 11 až 13 zmysel. Argument e je nepoužitý a premenná el je k ničomu - je to lokálna premenná, ktorá zanikne po skončení vnorenej funkcie.
Chamurappi
Profil
Reaguji na _es:
A akým spôsobom je uvedená metóda volaná?
Tipnul bych si, že this.togglePlaylist přiřazuje do nějakého onclicku (napovídá tomu i argument e s targetem). Pak je při vzniku události v this element, na němž je událost zachytávána. A ten tudíž nemá vlastnost el.
xROAL
Profil
Tak som potom vážne špatne pochopil koncept. Očakával by som, že this bude referovať na objekt/inštanciu bez ohľadu na spôsob volania metódy. (JS mi s týmto this dáva ozaj zabrať. Ale aspoň som zase o niečo múdrejší.)

Metóda je naozaj volaná cez onclick a teda, ako som až na základe vašich správ zistil, pod this je v danej metóde práve DIV na ktorý bolo kliknuté.

Vyriešil som to teda použitím var that = this; a v metóde namiesto this používať that.

Ďakujem za rady, samého by ma to asi nenapadlo ;)
Joker
Profil
xROAL:
Očakával by som, že this bude referovať na objekt/inštanciu bez ohľadu na spôsob volania metódy.
To sice platí, ale tady nejde o způsob volání metody, ale o přiřazení metody.

Tzn. když budu mít například:
var foo = { "id" : "foo", "fn" : function() { return this.id }}; 
var bar = {"id" : "bar"};
tak přiřazení nějaké metody objektu:
bar.fn = foo.fn; // bar.fn() vrátí "bar"
není to samé, jako vytvoření metody, která volá jinou metodu:
bar.fn = function() { return foo.fn(); }  // bar.fn() vrátí "foo"

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: