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

VPS Starter Arubacloud
0 głosów
358 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ź 611 wizyt
pytanie zadane 23 kwietnia 2021 w PHP przez Tukan Nowicjusz (190 p.)
0 głosów
1 odpowiedź 187 wizyt
0 głosów
3 odpowiedzi 1,195 wizyt
pytanie zadane 5 kwietnia 2020 w C i C++ przez nanautzin Obywatel (1,510 p.)

92,452 zapytań

141,262 odpowiedzi

319,080 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...