• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Object Oriented JavaScript - pytanie

Cloud VPS
0 głosów
760 wizyt
pytanie zadane 17 listopada 2022 w JavaScript przez GniewoszPL Nowicjusz (160 p.)
edycja 17 listopada 2022 przez GniewoszPL

Hej.

Czy możecie wyjaśnić mi dlaczego na załączonym screenie this.menuElements działają bez problemu wewnątrz jednej funkcji w ramach klasy, ale już nie działają w ramach innej funkcji - umieszczonej w tej samej klasie?

 

class Tabs {
    constructor(selector) {
        this.menuElements = document.querySelectorAll(selector);

        if ( !this.menuElements ) {
            return;
        }

        this.menuElementsClick();
    }

    menuElementsClick() {
        for (var i = 0; i < this.menuElements.length; i++) {
            this.menuElements[i].addEventListener("click", this.change, false);
        }

        
    }

    change(e) {

        for (var i = 0; i < this.menuElements.length; i++) {
            this.menuElements[i].classList.remove('active');
            const id = this.menuElements[i].getAttribute('data-tab');
            document.getElementById(id).classList.remove('active');
        }


        e.target.classList.add('active');
        const id = e.currentTarget.getAttribute('data-tab');
        document.getElementById(id).classList.add('active');
    }
}

export default Tabs;



komentarz 17 listopada 2022 przez Comandeer Guru (607,100 p.)
Wstaw kod przy pomocy odpowiedniej funkcji edytora – będzie zdecydowanie łatwiej zauważyć, co się dzieje, niż na screenie.

3 odpowiedzi

+2 głosów
odpowiedź 17 listopada 2022 przez ScriptyChris Mędrzec (190,190 p.)

Domyślam się, że this jest gubiony wewnątrz metody changethis domyślnie jest ustawiane w momencie wywołania funkcji. Do event listenera przekazujesz this.change i w tym samym momencie kontekst jest gubiony, a już sam listener woła tą funkcję jako samo change (bez kontekstu, czyli domyślnie window lub undefined w zależności czy jest to strict mode).

W tym artykule jest to dobrze wytłumaczone https://javascript.info/reference-type

Możesz to naprawić poprzez:

  • przekazanie arrow function: (event) => this.change(event)
  • zbindowanie funkcji: this.change.bind(this)
+2 głosów
odpowiedź 17 listopada 2022 przez Comandeer Guru (607,100 p.)

Bo w chwili, gdy change() jest wywoływane jako event listener, to jego this jest zmienione (na element, na którym doszło do zdarzenia).

Są dwa rozwiązania:

  1. arrow function,
  2. Function.prototype.bind().

Arrow function pozwala na zachowanie kontekstu this, więc wystarczy otoczyć event listener w taką funkcję:

element.addEventListener( 'click', ( event ) => {
    this.change( event );
} );

Z kolei bind() pozwala stworzyć kopię danej funkcji, która ma na stałe przypisany konkretny kontekst, stąd też można to wykorzystać:

element.addEventListener( 'click', this.change.bind( this ) );

Pierwsze rozwiązanie jest IMO ciut ładniejsze + nie tworzymy dodatkowej kopii metody change().

komentarz 17 listopada 2022 przez GniewoszPL Nowicjusz (160 p.)
Hmm, czyli w pierwszym przypadku musiałbym wywoływać całą funkcję jako callback event listenera? Nie ma jakiegoś syntaxu, który pozwoliłby użyć change jako osobna metoda dla tej klasy, ale z arrow function?

Jeśli odpowiedź na powyższe brzmi - nie, to zostaje mi bind tylko, prawda?
0 głosów
odpowiedź 17 listopada 2022 przez GniewoszPL Nowicjusz (160 p.)
Dzięki Panowie - wszystko działa jak należy - tak jak pisaliście :)

Podobne pytania

0 głosów
2 odpowiedzi 1,236 wizyt
pytanie zadane 25 lipca 2015 w PHP przez Aurelian Spodarec Użytkownik (920 p.)
0 głosów
0 odpowiedzi 133 wizyt
pytanie zadane 11 grudnia 2018 w PHP przez s4bek Użytkownik (600 p.)
0 głosów
0 odpowiedzi 147 wizyt
pytanie zadane 5 grudnia 2018 w PHP przez s4bek Użytkownik (600 p.)

93,467 zapytań

142,461 odpowiedzi

322,739 komentarzy

62,848 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Kursy INF.02 i INF.03
...