• 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]

0 głosów
123 wizyt
pytanie zadane 2 stycznia 2021 w JavaScript przez Oskar Szkurłat Bywalec (2,620 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 (180,980 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,620 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 (180,980 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,620 p.)
Dziękuję bardzo, pomogło. :)
komentarz 2 stycznia 2021 przez ScriptyChris Mędrzec (180,980 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ź 168 wizyt
pytanie zadane 23 kwietnia 2021 w PHP przez Tukan Nowicjusz (190 p.)
0 głosów
1 odpowiedź 121 wizyt
0 głosów
3 odpowiedzi 666 wizyt
pytanie zadane 5 kwietnia 2020 w C i C++ przez nanautzin Użytkownik (910 p.)

88,359 zapytań

136,957 odpowiedzi

305,679 komentarzy

58,623 pasjonatów

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...