Wątek przeniesiony 2015-11-13 12:32 z Webmastering przez dzek69.

JS undefined length of variable

0

Witam!

Mam pewien problem.

Kod:

      var user = {
          uid: 2,
          colors: ['red', 'blue', 'orange', 'darkorange', 'darkgreen', 'green', 'lime'],
          color: this.colors[Math.round(Math.random() * this.colors.length)]
       }

Zwraca w konsoli: Uncaught TypeError: Cannot read property 'length' of undefined

Czemu? Dziwny błąd :/

0

Błąd jest chyba oczywisty. Próbujesz dobrać się do właściwości length na niezdefiniowanej zmiennej (u Ciebie this.colors).

PS. Następne posty bez znaczników <code=nazwa_jezyka></code> będę wyrzucał

0

A TypeError is thrown when an operand or argument passed to a function is incompatible with the type expected by that operator or function.

A ReferenceError is thrown when trying to dereference a variable that has not been declared.

Musisz sobie wbić do głowy te dwie definicje i będzie Ci łatwiej szukać błędów, bo będziesz wiedział jakich błędów szukasz.

Cannot read property 'length' of undefined
Patrzysz gdzie próbujesz odczytać to length i zauważasz, że jest to this.colors. Przeglądarka Ci powiedziała, że jest to równe undefined - no ale jak to? Tak to, że jest to globalny obiekt Window. Jeżeli nie użyjesz tego w funkcji, a tej funkcji nie wywołasz na obiekcie user (czyli user.jakaś_funkcja) to this cały czas będzie pokazywało na obiekt window. Tak działa this w js (z grubsza).

Przy debugowaniu skorzystaj z takiego cudu jak debugger; po prostu dopisz to w którymś miejscu i przeglądarka zatrzyma egzekucje kodu i będziesz mógł w dev toolsach podejrzeć co siedzi pod jaką zmienną.

var x = { globalnyObiekt: this, obiektX: function() { return this; } }
x.globalnyObiekt
//Window {top: Window, location: Location, document: document, window: Window, external: Object…}
x.obiektX();
//Object {globalnyObiekt: Window, obiektX: function()}

Jeżeli teraz zrobisz tak:

var fnXCopy = x.obiektX;
fnXCopy();
//Window {top: Window, location: Location, document: document, window: Window, external: Object…}

To pod this będzie ukryte window. This nie jest przypięte do obiekty, tylko ma tzw. późne wiązanie. Ogólnie są 4 zasady (od góry do dołu, jeżeli chodzi o pierwszeństwo):

  1. Czy wywołałem funkcję z operatorem new? this pokazuje na obiekt przez nią zwrócony
  2. Czy użyłem bind, call, apply? this pokazuje na argument przekazany do tych funkcji
  3. Czy wywołałem funkcję "z kropką" tzn. user.funkcja() this pokazuje na ten obiekt( ale też nie zawsze, uwaga na np. setTimeout)
  4. this pokazuje na obiekt globalny

Jak widzisz w twoim przypadku zasada 4 ma zastosowanie. Odsyłam do dalszego poczytania, bo dosyć nieudolnie i po łebkach to wytłumaczyłem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1