JavaScript nu este un limbaj orientat pe obiecte bazat pe clase. Dar are încă modalități de utilizare a programării orientate pe obiecte (OOP).
în acest tutorial, vă voi explica OOP și vă voi arăta cum să îl utilizați.
conform Wikipedia, programarea bazată pe clase este
un stil de Programare orientată pe obiecte (OOP) în care moștenirea are loc prin definirea claselor de obiecte, în loc de moștenire care apare doar prin obiecte
cel mai popular model de OOP este bazat pe clase.
dar, așa cum am menționat, JavaScript nu este un langauge bazat pe clase-este un langauge bazat pe prototipuri.
conform documentului Mozilla:
un limbaj bazat pe prototip are noțiunea de obiect prototipic, un obiect folosit ca șablon din care să obțină proprietățile inițiale pentru un obiect nou.
uitați – vă la acest cod:
let names = { fname: "Dillion", lname: "Megida"}console.log(names.fname);console.log(names.hasOwnProperty("mname"));// Expected Output// Dillion// false
variabila obiect names
are doar două proprietăți – fname
și lname
. Nu există metode deloc.
deci de unde vinehasOwnProperty
?
Ei bine, vine de laObject
prototip.
încercați să conectați conținutul variabilei la consolă:
console.log(names);
când extindeți rezultatele în consolă, veți obține acest lucru:
observați ultima proprietate – __proto__
? Încercați să-l extindeți:
veți vedea un set de proprietăți subObject
constructor. Toate aceste proprietăți provin de la prototipul global Object
. Dacă vă uitați atent, veți observa și ID-ul nostru ascunshasOwnProperty
.
cu alte cuvinte, toate obiectele au acces la prototipulObject
. Ei nu posedă aceste proprietăți, dar li se acordă acces la proprietățile din prototip.
proprietatea __proto__
aceasta indică obiectul care este folosit ca prototip.
aceasta este proprietatea fiecărui obiect care îi oferă acces la proprietateaObject prototype
.
fiecare obiect are această proprietate în mod implicit, care se referă laObject Protoype
cu excepția cazului în care este configurat altfel (adică atunci când obiectul__proto__
este indicat către un alt prototip).
modificarea proprietății __proto__
această proprietate poate fi modificată precizând în mod explicit că ar trebui să se refere la un alt prototip. Următoarele metode sunt utilizate pentru a realiza acest lucru:
obiect.creați ()
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);
în consolă, aceasta este ceea ce aveți:
observați__proto__
proprietate șispeak
metodă?
Object.create
folosește argumentul transmis pentru a deveni prototipul.
cuvânt cheie nou
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
__proto__
proprietatea este direcționată cătreDogObject
prototip. Dar amintiți-vă, DogObject
prototipul este un obiect (pereche cheie și valoare), prin urmare are și o __proto__
proprietate care se referă la Object
protoype.
această tehnică este denumită înlănțuirea prototipului.
rețineți că:new
abordarea de cuvinte cheie face același lucru caObject.create()
dar numai face mai ușor, deoarece face unele lucruri în mod automat pentru tine.
și așa mai departe…
fiecare obiect din Javascript are acces la prototipulObject
în mod implicit. Dacă este configurat să utilizeze un alt prototip, spuneți prototype2
, atunci prototype2
ar avea, de asemenea, acces la prototipul obiectului în mod implicit și așa mai departe.
combinație obiect + funcție
probabil sunteți confuz de faptul căDogObject
este o funcție (function DogObject(){}
) și are proprietăți accesate cu o notație punct. Aceasta este menționată ca o combinație obiect funcție.
când funcțiile sunt declarate, în mod implicit li se oferă o mulțime de proprietăți atașate acesteia. Amintiți-vă că funcțiile sunt, de asemenea, obiecte în tipurile de date JavaScript.
acum, clasa
JavaScript a introdusclass
cuvânt cheie în ECMAScript 2015. Se face JavaScript par ca un limbaj OOP. Dar este doar zahăr sintatic peste tehnica de prototipare existentă. Își continuă prototiparea în fundal, dar face ca corpul exterior să arate ca OOP. Ne vom uita acum la modul în care acest lucru este posibil.
următorul exemplu este o utilizare generală a unui class
în JavaScript:
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);
acesta este rezultatul în consola:
__proto__
face referire la Animals
prototip (care la rândul său face referire la Object
prototip).
Din aceasta, putem vedea că constructorul definește caracteristicile majore în timp ce tot ceea ce este în afara constructorului (sing()
șidance()
) sunt caracteristicile bonus (prototipuri).
în fundal, folosind new
abordare de cuvinte cheie, cele de mai sus se traduce în:
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");
Subclasare
aceasta este o caracteristică în OOP unde o clasă moștenește caracteristici dintr-o clasă părinte, dar posedă caracteristici suplimentare pe care părintele nu le are.
ideea de aici este, spuneți că doriți să creați o clasă de pisici. În loc să creați clasa de la zero – declarând din nou numele, vârsta și proprietatea speciilor, ați moșteni acele proprietăți de la clasa animalelor părinte.
această clasă de pisici poate avea apoi proprietăți suplimentare, cum ar fi culoarea mustăților.
Să vedem cum se fac subclasele cuclass
.aici avem nevoie de un părinte de la care moștenește subclasa. Examinați următorul cod:
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");
cu cele de mai sus, obținem următoarele ieșiri:
console.log(clara.sing());console.log(clara.whiskers());// Expected Output// "Clara can sing"// "I have indigo whiskers"
când conectați conținutul Clarei în consolă, avem:
veți observa că clara
are o __proto__
proprietate care face referire la constructor Cats
și primește acces la whiskers()
metodă. Această proprietate__proto__
are și o proprietate__proto__
care face referire la constructorulAnimals
obținând astfel acces lasing()
șidance()
name
și age
sunt proprietăți care există pe fiecare obiect creat din aceasta.
folosindObject.create
metoda de abordare, mai sus se traduce la:
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
este o metodă care ia în două argumente – obiectul (primul argument) și prototipul dorit (al doilea argument).
Din cele de mai sus,Animals
funcția returnează un obiect cuanimalConstructor
ca prototip. FuncțiaCats
returnează un obiect cucatConstructor
ca prototip. catConstructor
pe de altă parte, este dat un prototip deanimalConstructor
.
prin urmare, animalele obișnuite au acces doar laanimalConstructor
dar pisicile au acces lacatConstructor
șianimalConstructor
.
Wrapping Up
JavaScript folosește natura sa prototip pentru a primi dezvoltatorii OOP în ecosistemul său. De asemenea, oferă modalități ușoare de a crea prototipuri și de a organiza date conexe.
limbile OOP adevărate nu efectuează prototipuri în fundal – luați notă de asta.
Un mare datorită cursului lui Will Sentance pe frontend Masters – JavaScript: părțile dure ale JavaScript orientat obiect. Am învățat tot ce vedeți în acest articol (plus o mică cercetare suplimentară) din cursul său. Ar trebui să verifici.
puteți să mă lovit pe Twitter la iamdillion pentru orice întrebări sau contribuții.
Vă mulțumim pentru lectură : )