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

Object Oriented JavaScript - pytanie

Object Storage Arubacloud
0 głosów
442 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 (600,810 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 (600,810 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,108 wizyt
pytanie zadane 25 lipca 2015 w PHP przez Aurelian Spodarec Użytkownik (920 p.)
0 głosów
0 odpowiedzi 108 wizyt
pytanie zadane 11 grudnia 2018 w PHP przez s4bek Użytkownik (600 p.)
0 głosów
0 odpowiedzi 130 wizyt
pytanie zadane 5 grudnia 2018 w PHP przez s4bek Użytkownik (600 p.)

92,551 zapytań

141,393 odpowiedzi

319,523 komentarzy

61,936 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...