JavaScript ei ole luokkapohjainen oliopohjainen kieli. Mutta se on edelleen tapoja käyttää object oriented programming (OOP).
tässä opetusohjelmassa selitän OOP: n ja näytän, miten sitä käytetään.
Wikipedian mukaan luokkapohjainen ohjelmointi on
oliopohjaisen ohjelmoinnin (OOP) tyyli, jossa periytyminen tapahtuu olioluokkien määrittelyn kautta, sen sijaan että periytyminen tapahtuisi pelkästään olioiden kautta
suosituin OOP: n malli on luokkapohjainen.
mutta kuten mainitsin, JavaScript ei ole luokkapohjainen langauge-se on prototyyppipohjainen langauge.
Mozillan dokumentin mukaan:
prototyyppipohjaisella kielellä on käsite prototyyppinen olio, olio, jota käytetään mallina, josta saadaan uuden olion alkuominaisuudet.
katso tätä koodia:
let names = { fname: "Dillion", lname: "Megida"}console.log(names.fname);console.log(names.hasOwnProperty("mname"));// Expected Output// Dillion// false
kohdemuuttujalla names
on vain kaksi ominaisuutta – fname
ja lname
. Ei menetelmiä ollenkaan.
Joten mistä hasOwnProperty
tulee?
no, se tulee Object
prototyypistä.
kokeile kirjata muuttujan sisältö konsoliin:
console.log(names);
kun laajennat tuloksia konsolissa, saat tämän:
huomaa viimeinen ominaisuus – __proto__
? Kokeile laajentaa sitä:
näet joukon ominaisuuksia Object
rakentaja. Kaikki nämä ominaisuudet ovat peräisin globaalista Object
prototyypistä. Jos katsoo tarkkaan, huomaa myös meidän kätketty hasOwnProperty
.
toisin sanoen kaikilla olioilla on pääsy Object
n prototyyppiin. Heillä ei ole näitä ominaisuuksia, mutta heille myönnetään pääsy prototyypin ominaisuuksiin.
__proto__ ominaisuus
tämä osoittaa prototyyppinä käytettävän kohteen.
Tämä on jokaisen kohteen ominaisuus, joka antaa sille pääsyn Object prototype
ominaisuus.
jokaisella esineellä on oletusarvoisesti tämä ominaisuus, joka viittaa Object Protoype
, paitsi jos se on konfiguroitu toisin (eli kun kohteen __proto__
osoitetaan toiseen prototyyppiin).
muokkaamalla __proto__ ominaisuutta
tätä ominaisuutta voidaan muuttaa toteamalla nimenomaisesti, että sen pitäisi viitata toiseen prototyyppiin. Tämän saavuttamiseksi käytetään seuraavia menetelmiä:
objekti.luo ()
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);
konsolissa näin olisi:
Notice the __proto__
property and the speak
method?
Object.create
käyttää prototyypiksi sille siirrettyä argumenttia.
Uusi avainsana
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__
ominaisuus on suunnattu DogObject
’s prototyyppi. Mutta muista, että DogObject
n prototyyppi on objekti (avain-ja arvopari), joten sillä on myös __proto__
ominaisuus, joka viittaa globaaliin Object
prototyyppi.
tätä tekniikkaa kutsutaan PROTOTYYPPIKETJUKSI.
huomaa, että: new
keyword approach tekee saman kuin , mutta vain helpottaa, koska se tekee joitakin asioita automaattisesti sinulle.
ja niin…
jokaisella JavaScriptin objektilla on oletusarvoisesti käytössään Object
n prototyyppi. Jos määritetty käyttämään toista prototyyppiä, sano prototype2
, niin prototype2
saisi myös oletusarvoisesti käyttöoikeuden kohteen prototyyppiin, ja niin edelleen.
objekti + Funktioyhdistelmä
sinua hämmentänee se, että DogObject
on funktio (function DogObject(){}
) ja sillä on ominaisuuksia, joihin pääsee pistemerkinnällä. Tätä kutsutaan funktioobjektien yhdistelmäksi.
kun funktiot julistetaan, niille annetaan oletusarvoisesti paljon siihen liitettyjä ominaisuuksia. Muista, että funktiot ovat objekteja myös JavaScript-tietotyypeissä.
nyt, Luokka
JavaScript otti käyttöön class
avainsanan ECMAScript 2015: ssä. Se saa JavaScriptin näyttämään OOP-kieleltä. Mutta se on vain syntaattista sokeria olemassa olevan prototyyppitekniikan päälle. Se jatkaa prototyyppejään taustalla, mutta saa ulkorungon näyttämään OOP: lta. Katsotaan nyt, miten se on mahdollista.
seuraava esimerkki on class
Javascriptissä:
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);
Tämä on konsolin tulos:
__proto__
viittaa Animals
prototyyppiin (joka puolestaan viittaa Object
prototyyppiin).
tästä voidaan nähdä, että konstruktori määrittelee tärkeimmät ominaisuudet, kun taas kaikki konstruktorin ulkopuolella (sing()
ja dance()
) ovat bonusominaisuuksia (prototyyppejä).
taustalla, käyttäen new
avainsanamallia, edellä oleva tarkoittaa:
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");
aliluokka
Tämä on ominaisuus OOP: ssa, jossa luokka perii ominaisuuksia vanhemmalta luokalta, mutta sillä on lisäominaisuuksia, joita vanhemmalla ei ole.
idea tässä on esimerkiksi sano, että haluat luoda Kissakurssin. Sen sijaan, että loisit luokan tyhjästä-ilmoittaisit nimen, iän ja lajiomaisuuden uudelleen, perisit nuo ominaisuudet vanhempainluokalta.
tällä kissaluokalla voi sitten olla ylimääräisiä ominaisuuksia, kuten viiksien väri.
katsotaan, miten alaluokat tehdään class
.
tässä tarvitaan vanhempi, jolta alaluokka perii. Tarkastellaan seuraavaa koodia:
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");
yllä olevalla saadaan seuraavat lähdöt:
console.log(clara.sing());console.log(clara.whiskers());// Expected Output// "Clara can sing"// "I have indigo whiskers"
kun Claran sisällön kirjaat ulos konsoliin, meillä on:
huomaat, että clara
on __proto__
kiinteistö, joka viittaa rakennuttajaan Cats
ja saa käyttöönsä whiskers()
menetelmä. Tällä __proto__
kiinteistöllä on myös __proto__
kiinteistö, joka viittaa rakennuttajaan Animals
siten, että se saa käyttöoikeuden sing()
ja dance()
name
ja age
ovat ominaisuuksia, jotka ovat olemassa jokaisella tämän perusteella luodulla objektilla.
käyttämällä Object.create
method approach, edellä oleva tarkoittaa:
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
on menetelmä, jossa käytetään kahta argumenttia – objektia (ensimmäinen argumentti) ja haluttua prototyyppiä (toinen argumentti).
edellä mainitusta Animals
funktio palauttaa objektin animalConstructor
prototyyppinä. Cats
funktio palauttaa objektin catConstructor
sen prototyyppinä. catConstructor
sen sijaan animalConstructor
.
näin ollen tavallisilla eläimillä on pääsy vain animalConstructor
, mutta kissoilla catConstructor
ja animalConstructor
.
JavaScript hyödyntää prototyyppiluonnettaan toivottaakseen OOP: n kehittäjät tervetulleiksi ekosysteemiinsä. Se tarjoaa myös helppoja tapoja luoda prototyyppejä ja järjestää niihin liittyviä tietoja.
todelliset OOP – kielet eivät tee prototyyppejä taustalla-huomioikaa vain se.
iso kiitos Will Sentancen kurssille frontend Masters – JavaScript: the Hard Parts of Object Oriented JavaScript. Opin kaiken näet tässä artikkelissa (plus hieman ylimääräistä tutkimusta) hänen tietenkin. Sinun pitäisi tarkistaa se.
voit iskeä minut ylös Twitterissä osoitteessa iamdillion kysyttävää tai kannanottoja.
kiitos lukemisesta:)