Veidojam JavaScript klases!

Izlasot šo rakstu jūs iegūsiet zināšanas, lai izprastu un ar piemēriem spētu izskaidrot klašu paplašināšanas koncepciju, izmantojot pamata mantojumu, lai mainītu uzvedību “bērnu” klasēs.

Tagad jums vajadzētu zināt, ka JavaScript mantojuma pamatā ir prototipa objekts.

Visiem objektiem, kas ir veidoti no prototipa, ir viena un tā pati funkcionalitāte.

Par prototipiem un prototipēšanu varat izlasīt kādā no maniem iepriekšējiem rakstiem šajā blogā.

Ja nepieciešams kodēt sarežģītākas OOP attiecības, varat izmantot klases atslēgvārdu un tā viegli saprotamo un viegli pamatoto sintaksi.

Iedomājieties, ka jums ir jākodē vilciena klase.

Kad būsiet iekodējis šo klasi, varēsiet izmantot atslēgvārdu New, lai ģenerētu klases Vilciens objektus.

Tomēr pagaidām vispirms ir jādefinē vilciena klase, izmantojot šādu sintaksi:

class Vilciens {}

Tātad, jūs izmantojat klases atslēgvārdu, pēc tam norādiet savas klases nosaukumu, pirmo burtu rakstot ar lielo burtu, un pēc tam pievienojat sākuma un beigu krokaino figūriekavu.

Starp figūriekavām pirmā koda daļa, kas jums jādefinē, ir konstruktors:

class Vilciens {
    constructor() {


    }
}

Konstruktors tiks izmantots, lai izveidotu rekvizītus nākotnes vilcienu klases objekta instancē.

Pagaidām pieņemsim, ka katram Vilciens klases objekta eksemplāram ir jābūt tikai diviem rekvizītiem, kad tas tiek iemiesots: krāsa un gaismasIr :

class Vilciens {
    constructor(krāsa, gaismasIr) {
        this.krāsa = krāsa;
        this.gaismasIr = gaismasIr;


    }
}

Ievērojiet konstruktora sintaksi. Manā Vilciens klasē konstruktors ir īpaša funkcija.

Pirmkārt, ievērojiet, ka nav funkcijas atslēgvārda. Ņemiet vērā arī to, ka šīs funkcijas definēšanai tiek izmantots atslēgvārdu konstruktors. Konstruktora funkcijas parametrus ievadāt atverošās un aizverošās iekavās, tāpat kā parastajās funkcijās. Parametru nosaukumi ir krāsa un gaismasIr.

Pēc tam konstruktora funkcijas pamattekstā jūs piešķīrāt nodotā krāsas parametra vērtību parametram this.krāsa un nodotā parametra gaismasIr vērtību parametram this.gaismasIr.

Ko šis atslēgvārds nozīmē?

Tas ir klases Vilciens nākotnes objekta gadījums.

Būtībā šis ir viss kods, kas jums jāieraksta, lai sasniegtu divas lietas:

  1. Šis kods ļauj man izveidot jaunus vilcienu klases gadījumus.
  2. Katrai manis izveidotajai Vilciens klases objekta eksemplāram būs savas pielāgotās krāsas un gaismas ieslēgšanas īpašības.

Tagad, lai faktiski izveidotu jaunu Vilciensklases gadījumu, man ir jāizmanto šāda sintakse:

new Train()

Iekavās ir jānorāda tādas vērtības kā, piemēram, “red”un false, kas nozīmē, ka rekvizīts krāsa ir iestatīts uz “red” un rekvizīts gaismasIr ir iestatīts uz false.

Un, lai varētu mijiedarboties ar jauno objektu, kas izveidots šādā veidā, jums tas ir jāpiešķir mainīgajam.

Saliekot visu kopā, lūk, jūsu pirmais vilciens:

class Vilciens {
  constructor(krāsa, gaismasIr) {
    this.krāsa = krāsa;
    this.gaismasIr = gaismasIr;
  }
}
var mansPirmaisVilciens = new Vilciens("red", false);

Tāpat ,kā jebkuru citu mainīgo, tagad varat, konsolē izvadīt objektu mansPirmaisVilciens :

class Vilciens {
  constructor(krāsa, gaismasIr) {
    this.krāsa = krāsa;
    this.gaismasIr = gaismasIr;
  }
}
var mansPirmaisVilciens = new Vilciens("sarkans", false);


console.log(mansPirmaisVilciens); // Vilciens {'krāsa': 'sarkans', gaismasIr: false}

konsole izvadīs šādu rezultātu:

Vilciens { 'krāsa': 'sarkans', gaismasIr: false }
Varat turpināt veidot klases Vilciens gadījumus. Pat ja piešķirat tiem tieši tādas pašas īpašības, tie joprojām ir atsevišķi objekti.

Tomēr tas nav viss, ko var piedāvāt šī pamācība par klasēm.

Varat arī pievienot metodes klasēm, un šīs metodes tiks koplietotas visiem turpmākajiem manas Train klases instanču objektiem.

Piemēram:

class Vilciens {
  constructor(krāsa, gaismasIr) {
    this.krāsa = krāsa;
    this.gaismasIr = gaismasIr;
  }
  gaismasSlēdzis() {
    this.gaismasIr = !this.gaismasIr;
  }
  gaismuStatuss() {
    console.log("Gaismas ieslēgtas?", this.gaismasIr);
  }
  paķerSev() {
    console.log(this);
  }
  paņemPrototipu() {
    var proto = Object.paņemPrototipuNoŠī(this);
    console.log(proto);
  }
}

Tagad jūsu vilciena klasē ir četras metodes:
gaismasSlēdzis(), gaismuStatuss(), paķerSev() un paņemPrototipu().

Metode gaismasSlēdzis izmanto loģisko, nevis operatoru !. Šis operators mainīs vilciena klases nākotnes instances objekta gaismasIr rekvizītā saglabāto vērtību; līdz ar to !this.gaismasIr. Un operators = pa kreisi nozīmē, ka tas tiks piešķirts this.gaismasIr, kas nozīmē, ka tas kļūs par jauno gaismasIr rekvizīta vērtību konkrētajā instances objektā.

Metode gaismuStatuss() klasē Vilciens tikai ziņo par konkrētā objekta instances mainīgā gaismasIrpašreizējo statusu.

Metode paķerSev() izdrukā rekvizītus objekta instancē, kuru tā izsauc.

Konsole paņemPrototipu() reģistrē Vilciens klases objekta instances prototipu. Prototipam ir visi rekvizīti, kas ir kopīgi visiem Vilciens klases objektu gadījumiem. Lai iegūtu prototipu, jums būs jāizmanto JavaScript iebūvētā metode Object.getPrototypeOf() un jānodod tam šis objekts, kas nozīmē objekta gadījumu, kurā šī metode tiek izsaukta.

Tagad varat izveidot pavisam jaunu vilcienu, izmantojot šo atjaunināto vilcienu klasi:

var vilciens4 = new Vilciens("sarkans", false);

Tātad tagad, šajā kodā…

class Vilciens {
  constructor(krāsa, gaismasIr) {
    this.krāsa = krāsa;
    this.gaismasIr = gaismasIr;
  }
  gaismasSlēdzis() {
    this.gaismasIr = !this.gaismasIr;
  }
  gaismuStatuss() {
    console.log("Gaismas ieslēgtas?", this.gaismasIr);
  }
  paķerSev() {
    console.log(this);
  }
  paņemPrototipu() {
    var proto = Object.getPrototypeOf(this);


    console.log(proto);
  }
}
var vilciens4 = new Vilciens("sarkans", false);


vilciens4.gaismasSlēdzis();
vilciens4.gaismuStatuss();
vilciens4.paķerSev();
vilciens4.paņemPrototipu();

 

Konstruktora funkcija Vilciens definē jaunu klasi ar diviem laukiem – krāsa un gaismasIr. Tālāk tiek definētas 4 metodes – gaismasSlēdzis, gaismuStatuss, paķerSev un paņemPrototipu.

Metode gaismasSlēdzis maina lauka gaismasIr vērtību uz pretējo, t.i., ja tā ir true, tad tā kļūst par false un otrādi.

Metode gaismuStatuss izdrukā konsolē tekstu “Gaismas ieslēgtas?”, kurā tiek izmantots lauks gaismasIr.

Metode paķerSev izdrukā konsolē objektu, kurā tiek izmantots this.

Metode paņemPrototipu izdrukā konsolē prototipa objektu, kurš ir objektam, uz kuru attiecas this.

Pēc tam tiek izveidots jauns objekts vilciens4 no klases Vilciens, un tai tiek piešķirti divi parametri – “sarkans” un false. Tālāk tiek izsauktas visas 4 metodes, un tās izpildīsies secīgi.

 

Noslēguma papildinājums

Noslēgumā jāsaka, ka JavaScript klases sintakse ļauj mums skaidri nodalīt atsevišķu objektu datus, kas pastāv pašā objekta instancē, no koplietojamā objekta funkcionalitātes (metodēm), kas pastāv prototipā un ir kopīgas visiem objekta gadījumiem.

Tomēr tas nav viss stāsts.

Ir iespējams ieviest polimorfismu, izmantojot JavaScript klases, mantojot no bāzes klases un pēc tam ignorējot mantoto uzvedību. Lai saprastu, kā tas darbojas, vislabāk ir izmantot piemēru.

Nākamajā kodā jūs redzēsit, ka tiek kodēta cita klase, kuras nosaukums ir ĀtrVilciens un kas pārņem no klases Vilciens.

Tas padara Train klasi par bāzes klasi vai ĀtrVilciens klases superklasi. Citiem vārdiem sakot, ĀtrVilciens klase kļūst par Vilciens klases apakšklasi, jo tā ir mantota no tās.

Lai pārmantotu no vienas klases uz jaunu apakšklasi, JavaScript nodrošina paplašināto atslēgvārdu, kas darbojas šādi:

class ĀtrVilciens extends Vilciens {
}

Tāpat kā iepriekš minētajā piemērā, apakšklases sintakse atbilst tam, kā JavaScript ir definēta bāzes klase. Vienīgais papildinājums šeit ir paplašinājuma atslēgvārds un tās klases nosaukums, no kuras apakšklase ir mantota.

Tagad varat aprakstīt, kā darbojas ĀtrVilciens. Atkal varat sākt, definējot tā konstruktora funkciju:

class ĀtrVilciens extends Vilciens {
    constructor(pasažieri, paātrinājumsIr, krāsa, gaismasIr) {
        super(krāsa, gaismasIr);
        this.pasažieri = pasažieri;
        this.paātrinājumsIr = paātrinājumsIr;
    }
}

Ievērojiet nelielu sintakses atšķirību ĀtrVilciens klases konstruktorā, proti, super atslēgvārda izmantošanu.

JavaScript klasēs super tiek izmantotas, lai norādītu, kurš rekvizīts tiek mantots no apakšklases superklases.

Šajā gadījumā es izvēlos mantot abus īpašumus no ĀtrVilciens apakšklases Super-klases Vilciens.

Šīs īpašības ir krāsa un gaismas ieslēgšana.

Tālāk jūs pievienojat ĀtrVilciens klases papildu rekvizītus tās konstruktorā, proti, pasažierus un paātrinājumsIr rekvizītus.

Pēc tam konstruktora pamattekstā izmantojiet atslēgvārdu super un nododiet mantotās krāsas un gaismasIr rekvizītus, kas nāk no klases Vilciens. Nākamajās līnijās jūs piešķirat pasažierus this.pasažieriem un paātrinājumsIr this.paātrinājumsIr.

Ņemiet vērā, ka papildus mantotajām īpašībām jūs automātiski mantojat arī visas Vilciens prototipa esošās metodes, proti, gaismasSlēdzis(), gaismuStatuss(), paķerSev() un paķerPrototipu() metodes.

Tagad pievienosim vēl vienu metodi, kas būs raksturīga ĀtrVilciens klasei: ieslēgtPaātrinājumu() metodi.

class ĀtrVilciens extends Vilciens {
  constructor(pasažieri, paātrinājumsIr, krāsa, gaismasIr) {
    super(krāsa, gaismasIr);
    this.pasažieri = pasažieri;
    this.paātrinājumsIr = paātrinājumsIr;
  }
  ieslēgtPaātrinājumu() {
    this.paātrinājumsIr = !this.paātrinājumsIr;
    console.log("Paātrinājuma statuss:", this.paātrinājumsIr);
  }
}

Turklāt iedomājieties, ka sapratāt, ka jums nepatīk, kā darbojas

gaismasSlēdzis() metode no superklases, un vēlaties to ieviest nedaudz savādāk apakšklasē. Varat to pievienot ĀtrVilciens klasē.
class ĀtrVilciens extends Vilciens {
  constructor(pasažieri, paātrinājumsIr, krāsa, gaismasIr) {
    super(krāsa, gaismasIr);
    this.pasažieri = pasažieri;
    this.paātrinājumsIr = paātrinājumsIr;
  }
  ieslēgtPaātrinājumu() {
    this.paātrinājumsIr = !this.paātrinājumsIr;
    console.log("Paātrinājuma statuss:", this.paātrinājumsIr);
  }
  gaismasSlēdzis() {
    super.gaismasSlēdzis();
    super.gaismuStatuss();
    console.log('Gaismas ir 100% funkcionējošas.');
}

Tātad, kā jūs ignorējāt sākotnējās gaismasSlēdzis() metodes darbību?

Atcerēsimies, ka Superklasē metode gaismasSlēdzis() tika definēta šādi:

gaismasSlēdzis() {
    this.gaismasIr = !this.gaismasIr;
}

Atskatīsimies uz paveikto…

Jūs sapratāt, ka ĀtrVilciens metodei ir atkārtoti jāizmanto sākotnējās metodes gaismasSlēdzis() esošā darbība, un tāpēc izmantojāt super.gaismasSlēdzis() sintaksi, lai mantotu visu superklases metodi.

Pēc tam jūs mantojat arī superklases metodes gaismasIr() darbību, jo saprotat, ka vēlaties, lai rekvizīta gaismasIr atjauninātais statuss tiktu reģistrēts konsolē, ikreiz, kad apakšgrupā izsaucat metodi gaismasSlēdzis() klasē.

Visbeidzot, jūs pievienojat arī trešo rindiņu atkārtoti ieviestajā gaismasSlēdzis() metodē, proti:

console.log('Gaismas ir 100% funkcionējošas.');

Jūs pievienojāt šo trešo rindiņu, lai parādītu, ka varu apvienot “aizgūto” metodes kodu no superklases ar jūsu pielāgoto kodu apakšklasē.

Tagad esat gatavs būvēt dažādus vilciena objektus.

var Vilciens5 = new Vilciens('zils', false);
var ātrVilciens1 = new ĀtrVilciens(200, false, 'zaļš', false);

Jūs esat izveidojis vilciena klases objektu vilciens5 un iestatījis tā krāsu uz “zilu” un iestatījis gaismas iedegšanu uz nepatiesu jeb false.

Tālāk jūs esat izveidojis ātrvilciens1 objektu ĀtrVilciens klasei, iestatot pasažierus uz 200, paātrinājumsIr uz false, krāsu uz “zaļu” un gaismasIr uz false.

Tagad varat pārbaudīt vilciens5 darbību, izsaucot, piemēram, metodi gaismasSlēdzis() un pēc tam metodi gaismasStatuss():

Vilciens5.gaismasSlēdzis(); // undefined
train5.gaismasStatuss(); // Gaismas ir? true

Ja Jums viss izdevās kā mab, un rakstijāt kodu kopā ar mani, tad pilnam kodam vajadzētu izskatītes aptuveni šādi:

class Vilciens {
    constructor(krāsa, gaismasIr) {
        this.krāsa = krāsa;
        this.gaismasIr = gaismasIr;
    }
    gaismasSlēdzis() {
        this.gaismasIr = !this.gaismasIr;
    }
    gaismuStatuss() {
        console.log('Gaismas ieslēgtas?', this.gaismasIr);
    }
    paķerSev() {
        console.log(this);
    }
    paņemPrototipu() {
        var proto = Object.getPrototypeOf(this);
        console.log(proto);
    }
}


class ĀtrVilciens extends Vilciens {
    constructor(pasažieri, paātrinājumsIr, krāsa, gaismasIr) {
        super(krāsa, gaismasIr);
        this.pasažieri = pasažieri;
        this.paātrinājumsIr = paātrinājumsIr;
    }
    ieslēgtPaātrinājumu() {
        this.paātrinājumsIr = !this.paātrinājumsIr;
        console.log('Paātrinājuma statuss:', this.paātrinājumsIr);
    }
    gaismasSlēdzis() {
        super.gaismasSlēdzis();
        super.gaismuStatuss();
        console.log('Gaismas ir 100% funkcionējošas .');
    }
}


var mansPirmaisVilciens = new Vilciens('sarkans', false);
console.log(mansPirmaisVilciens); // Vilciens {krāsa: 'sarkans', gaismasIr: false}
var mansOtraisVilciens = new Vilciens('zils', false);
var mansTrešaisVilciens = new Vilciens('zils', false);


var vilciens4 = new Vilciens('sarkans', false);
train4.gaismasSlēdzis(); // undefined
train4.gaismuStatuss(); // Gaismas ieslēgtas? true
train4.paķerSev(); // Vilciens {krāsa: 'sarkans', gaismasIr: true}
train4.paņemPrototipu(); // {constructor: f, gaismasSlēdzis: f, gaismasStatus: f, paķerSev: f, paņemPrototipu: f}


var vilciens5 = new Vilciens('zils', false);
var ātrVilciens1 = new ĀtrVilciens(200, false, 'zaļš', false);


vilciens5.gaismasSlēdzis(); // undefined
vilciens5.gaismuStatuss(); // Gaismas ieslēgtas? true
ātrVilciens1.gaismasIr(); // Gaismas ieslēgtas? true, Gaismas ir 100% funkcionējošas.

Loading

Noderīgs raksts? Dalies ar citiem: