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

this z poziomu metody klasy - problem [JS]

Object Storage Arubacloud
0 głosów
372 wizyt
pytanie zadane 2 stycznia 2021 w JavaScript przez Oskar Szkurłat Bywalec (2,780 p.)

Cześć, miałbym takie pytanko - jak inaczej zapisać this, żeby była 'widoczność' z poziomu metody klasy do kontruktora?
Mam klasę Scanner i stworzyłem obiekt frontScanner. Klasa zawiera w konstruktorze np. piny (pinA/B/C/D). Problem jest w tym, że jak wywołuję z zewnątrz z metody obiektu (na samym dole dałem interwał), to zwraca dobre wartości, jednak z poziomu metody nie widzi zawartości konstruktora (ten console.log() w linii 64). Z poziomu metody zwraca undefined.
 

const rotConfig = {
    rotTime: 50, //rotation time for left&right sides
    stopTime: 0, //time to get rest
    stepsPerSide: 200, //limit of steps to change direction at motors
    degPerStep: 3 //each step of motor takes 3 deg
};
class Scanner {
    constructor(name, id, pinA, pinB, pinC, pinD, trigger, echo) {
        //Scanner construct
        this.name = name;
        this.id = id;
        this.output = [
            {
                points: [],
                lowest: 0,
                highest: 500,
                angle: 0
            }
        ];
        //Motor
        this.pinA = pinA;
        this.pinB = pinB;
        this.pinC = pinC;
        this.pinD = pinD;
        this.mtStep = 0;
        this.mtDir = true;
    }
    //************ Motor ************
    rotateScanner () {
        if ((this.angle >= rotConfig.stepsPerSide && this.mtDir == true) ||
            (this.angle <= -rotConfig.stepsPerSide && this.mtDir == false)) {
            this.mtDir = !scanner.mtDir;
        }
        if (this.mtDir) {
            switch (this.mtStep) {
                case 0:
                    board.digitalWrite(this.pinA, 1);
                    board.digitalWrite(this.pinB, 0);
                    board.digitalWrite(this.pinC, 0);
                    board.digitalWrite(this.pinD, 0);
                    break;
                //case 1-3:
				//Wycięto bo powielanie kodu
            }
        } else {
            switch (this.mtStep) {
                case 0:
                    board.digitalWrite(this.pinA, 0);
                    board.digitalWrite(this.pinB, 0);
                    board.digitalWrite(this.pinC, 0);
                    board.digitalWrite(this.pinD, 1);
                    break;
                //case 1-3:
				//Wycięto bo powielanie kodu
            }
        }
        if (this.mtDir == true)
            this.angle++;
        else
            this.angle--;
        this.mtStep++;
        if (this.mtStep > 3)
            this.mtStep = 0;
        console.log(this.pinA + ' , ' + this.pinB + ' , ' + this.pinC + ' , ' + this.pinD); //ZWRACA ŹLE - undefined
    }
    printf() {
        console.log('------name------');
        console.log(this.name);
        console.log('------id------');
        console.log(this.id);
        console.log('------output------');
        console.log(this.output);
        console.log('');
    }
}


var frontScanner = new Scanner('frontScanner', 0, 52, 50, 48, 46, 15, 14);

setInterval(function () {
        frontScanner.printf(); //ZWRACA POPRAWNIE
        console.log('pinB to ..... ' + frontScanner.pinB); //ZWRACA POPRAWNIE
    }, 3000);

Jak to inaczej zapisać? Z góry dziękuję!

komentarz 2 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Pokaż kod, którym wołasz metodę rotateScanner (ta, w której pod koniec odniesienie do pola przez this zwraca undefined).

komentarz 2 stycznia 2021 przez Oskar Szkurłat Bywalec (2,780 p.)
 //------- Interval: Rotate motors -------
    var rotateScannersInterval = setInterval(
        frontScanner.rotateScanner,
        rotConfig.rotTime + rotConfig.stopTime);

Funkcja się wykonuje, bo wyświetla konsolę, ale z wartościami złymi. Jest tu jakiś błąd?

1 odpowiedź

+2 głosów
odpowiedź 2 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 2 stycznia 2021 przez Oskar Szkurłat
 
Najlepsza

Przekazując metodę jako callback do wywołania, jego właściwy kontekst jest "tracony" i ustawiany jako window lub undefined (w zależności, czy kod jest wykonywany w trybie strict, czy nie) - możesz się upewnić wykonując w tej metodzie console.log('this:', this). Żeby wywołać tą metodę z prawidłowym kontekstem, owiń to w funkcję (strzałkową lub zwykłą) lub zbinduj this na obiekt frontScanner.

   var rotateScannersInterval = setInterval(
       frontScanner.rotateScanner.bind(frontScanner),
       rotConfig.rotTime + rotConfig.stopTime);

// lub

   var rotateScannersInterval = setInterval(
       () => frontScanner.rotateScanner(),
       rotConfig.rotTime + rotConfig.stopTime);

 

1
komentarz 2 stycznia 2021 przez Oskar Szkurłat Bywalec (2,780 p.)
Dziękuję bardzo, pomogło. :)
komentarz 2 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Przekazując metodę jako callback do wywołania

W sumie to jest niedopowiedzenie, bo też jeśli przypisze się referencję metody do innej zmiennej, to efekt jest ten sam (co jest wspomniane w pierwszym linku).

const rotateScannerMethod = frontScanner.rotateScanner; // <- tutaj też this będzie "stracony"

 

Podobne pytania

+1 głos
1 odpowiedź 654 wizyt
pytanie zadane 23 kwietnia 2021 w PHP przez Tukan Nowicjusz (190 p.)
0 głosów
1 odpowiedź 190 wizyt
0 głosów
3 odpowiedzi 1,207 wizyt
pytanie zadane 5 kwietnia 2020 w C i C++ przez nanautzin Obywatel (1,510 p.)

92,539 zapytań

141,382 odpowiedzi

319,480 komentarzy

61,928 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!

...