Objektile orienteeritud programmeerimine JavaScriptis - selgitatud näidetega

JavaScript ei ole klassipõhine objektile orienteeritud keel. Kuid sellel on endiselt võimalusi kasutada objektorienteeritud programmeerimist (OOP).

Selles õpetuses selgitan OOP-d ja näitan teile, kuidas seda kasutada.

Vikipeedia andmetel on klassipõhine programmeerimine nii

objekti orienteeritud programmeerimise (OOP) stiil, kus pärimine toimub objektide klasside määratlemise kaudu, mitte ainult objektide kaudu toimuva pärimise kaudu

OOP-i populaarseim mudel on klassipõhine.

Kuid nagu ma mainisin, ei ole JavaScript klassifitseeritud langauge - see on prototüübil põhinev langauge.

Mozilla dokumentide järgi:

Prototüüpipõhisel keelel on prototüüpse objekti mõiste - objekt, mida kasutatakse mallina, millest saab uue objekti algsed omadused.

Vaadake seda koodi:

let names = { fname: "Dillion", lname: "Megida" } console.log(names.fname); console.log(names.hasOwnProperty("mname")); // Expected Output // Dillion // false 

Objekti muutujal nameson ainult kaks omadust - fnameja lname. Meetodeid pole üldse.

Kust siis hasOwnPropertytuleb?

Noh, see tuleb Objectprototüübist.

Proovige muutuja sisu konsooli sisse logida.

console.log(names); 

Kui laiendate konsoolis tulemusi, saate selle:

Märka viimast omadust - __proto__? Proovige seda laiendada:

ObjectKonstruktori all näete omaduste komplekti . Kõik need omadused pärinevad globaalsest Objectprototüübist. Kui vaatate tähelepanelikult, märkate ka meie varjatud hasOwnProperty.

Teisisõnu on kõigil objektidel juurdepääs Objectprototüübile. Neil neid omadusi ei ole, kuid neile antakse juurdepääs prototüübi omadustele.

__proto__vara

See osutab objektile, mida kasutatakse prototüübina.

See on vara igal objektil, mis annab sellele Object prototypevarale juurdepääsu .

Igal objektil on see omadus vaikimisi, mis viitab sellele, välja Object Protoypearvatud juhul, kui see on konfigureeritud teisiti (see tähendab, et kui objekti objekt __proto__on suunatud teisele prototüübile).

Muutmine __proto__vara

Seda omadust saab muuta, öeldes selgesõnaliselt, et see peaks viitama mõnele teisele prototüübile. Selle saavutamiseks kasutatakse järgmisi meetodeid:

Object.create()

function DogObject(name, age) { let dog = Object.create(constructorObject); dog.name = name; dog.age = age; return dog; } let constructorObject = { speak: function(){ return "I am a dog" } } let bingo = DogObject("Bingo", 54); console.log(bingo); 

Konsoolis on see, mis teil on:

Kas märkate __proto__atribuuti ja speakmeetodit?

Object.create kasutab prototüübiks saamiseks talle edastatud argumenti.

new märksõna

function DogObject(name, age) { this.name = name; this.age = age; } DogObject.prototype.speak = function() { return "I am a dog"; } let john = new DogObject("John", 45); 

john's __proto__vara on suunatud DogObject' s prototüüp. Kuid pidage meeles, DogObjectet prototüüp on objekt ( võtme- ja väärtuspaar ), seega on sellel ka __proto__omadus, mis viitab globaalsele Objectprototüübile.

Seda tehnikat nimetatakse prototüübi ketideks .

Pange tähele, et:new märksõna lähenemine teeb sama asja nagu Object.create()vaid muudab lihtsamaks kui see mõned asjad teie jaoks automaatselt.

Ja nii...

Igal Javascripti objektil on Objectvaikimisi juurdepääs prototüübile. Kui konfigureeritud kasutama teise prototüübi, ütleme prototype2, siis prototype2oleks ka juurdepääsu objekti prototüüp vaikimisi ja nii edasi.

Objekt + funktsioonide kombinatsioon

Tõenäoliselt on teid segaduses fakt, et DogObjectsee on funktsioon ( function DogObject(){}) ja sellel on omadused, millele pääseb juurde punktmärkimisega . Seda nimetatakse funktsiooniobjektide kombinatsiooniks .

Funktsioonide deklareerimisel antakse neile vaikimisi palju omadusi. Pidage meeles, et funktsioonid on ka JavaScripti andmetüüpide objektid.

Nüüd, klass

JavaScript tutvustas classmärksõna ECMAScript 2015. See muudab JavaScripti tunduvat OOP-keelena. Kuid see on lihtsalt sünteetiline suhkur olemasoleva prototüüpimistehnika üle. See jätkab prototüüpide loomist taustal, kuid muudab väliskeha OOP-väliseks. Vaatame nüüd, kuidas see võimalik on.

Järgmine näide on a-i üldine kasutamine classJavaScriptis:

class Animals { constructor(name, specie) { this.name = name; this.specie = specie; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } let bingo = new Animals("Bingo", "Hairy"); console.log(bingo); 

See on tulemus konsoolis:

The __proto__ references the Animals prototype (which in turn references the Object prototype).

From this, we can see that the constructor defines the major features while everything outside the constructor (sing() and dance()) are the bonus features (prototypes).

In the background, using the new keyword approach, the above translates to:

function Animals(name, specie) { this.name = name; this.specie = specie; } Animals.prototype.sing = function(){ return `${this.name} can sing`; } Animals.prototype.dance = function() { return `${this.name} can dance`; } let Bingo = new Animals("Bingo", "Hairy"); 

Subclassing

This is a feature in OOP where a class inherits features from a parent class but possesses extra features which the parent doesn't.

The idea here is, for example, say you want to create a cats class. Instead of creating the class from scratch - stating the name, age and species property afresh, you'd inherit those properties from the parent animals class.

This cats class can then have extra properties like color of whiskers.

Let's see how subclasses are done with class.

Here, we need a parent which the subclass inherits from. Examine the following code:

class Animals { constructor(name, age) { this.name = name; this.age = age; } sing() { return `${this.name} can sing`; } dance() { return `${this.name} can dance`; } } class Cats extends Animals { constructor(name, age, whiskerColor) { super(name, age); this.whiskerColor = whiskerColor; } whiskers() { return `I have ${this.whiskerColor} whiskers`; } } let clara = new Cats("Clara", 33, "indigo"); 

With the above, we get the following outputs:

console.log(clara.sing()); console.log(clara.whiskers()); // Expected Output // "Clara can sing" // "I have indigo whiskers" 

When you log the contents of clara out in the console, we have:

You'll notice that clara has a __proto__ property which references the constructor Cats and gets access to the whiskers() method. This __proto__ property also has a __proto__ property which references the constructor Animals thereby getting access to sing() and dance(). name and age are properties that exist on every object created from this.

Using the Object.create method approach, the above translates to:

function Animals(name, age) { let newAnimal = Object.create(animalConstructor); newAnimal.name = name; newAnimal.age = age; return newAnimal; } let animalConstructor = { sing: function() { return `${this.name} can sing`; }, dance: function() { return `${this.name} can dance`; } } function Cats(name, age, whiskerColor) { let newCat = Animals(name, age); Object.setPrototypeOf(newCat, catConstructor); newCat.whiskerColor = whiskerColor; return newCat; } let catConstructor = { whiskers() { return `I have ${this.whiskerColor} whiskers`; } } Object.setPrototypeOf(catConstructor, animalConstructor); const clara = Cats("Clara", 33, "purple"); clara.sing(); clara.whiskers(); // Expected Output // "Clara can sing" // "I have purple whiskers" 

Object.setPrototypeOf is a method which takes in two arguments - the object (first argument) and the desired prototype (second argument).

From the above, the Animals function returns an object with the animalConstructor as prototype. The Cats function returns an object with catConstructor as it's prototype. catConstructor on the other hand, is given a prototype of animalConstructor.

Seetõttu tavalised loomad ainult juurdepääs animalConstructorkuid kassid on juurdepääs catConstructorja animalConstructor.

Pakkimine

JavaScript kasutab oma prototüübi olemust OOP arendajate tervitamiseks oma ökosüsteemis. See pakub ka lihtsaid viise prototüüpide loomiseks ja seotud andmete korrastamiseks.

Tõelised OOP-keeled ei tee prototüüpe taustal - võtke see lihtsalt teadmiseks.

Suur tänu Will Sentance'i kursusele Frontend Masters - JavaScript: objektile orienteeritud JavaScripti rasked osad. Õppisin kõik tema kursuselt kõik, mida selles artiklis näete (lisaks väike lisauuring). Peaksite seda kontrollima.

Kõigi küsimuste või kaastööde eest võite mind Twitteris aadressil iamdillion tabada.

Aitäh lugemast :)

Kasulikud ressursid

  • Objektorienteeritud JavaScripti algajatele
  • Sissejuhatus JavaScripti objektorienteeritud programmeerimisse