Maybaygiare.org

Blog Network

Programowanie obiektowe w języku JavaScript-wyjaśnione przykładami

JavaScript nie jest językiem obiektowym opartym na klasach. Ale nadal ma sposoby korzystania z programowania obiektowego (OOP).

w tym tutorialu wyjaśnię OOP i pokażę, jak z niego korzystać.

według Wikipedii programowanie oparte na klasach to

styl programowania obiektowego (OOP), w którym dziedziczenie następuje poprzez definiowanie klas obiektów, zamiast dziedziczenia za pośrednictwem samych obiektów

najpopularniejszym modelem OOP jest oparty na klasach.

ale jak już wspomniałem, JavaScript nie jest langauge opartym na klasach-to jest langauge oparty na prototypach.

według dokumentu Mozilli:

język oparty na prototypach ma pojęcie obiektu prototypowego, obiektu używanego jako szablon, z którego można uzyskać początkowe właściwości nowego obiektu.

spójrz na ten kod:

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

zmienna obiektu names ma tylko dwie właściwości – fname I lname . Żadnych metod.

skąd więc pochodzi hasOwnProperty?

pochodzi z prototypu Object.

spróbuj zalogować zawartość zmiennej do konsoli:

console.log(names);

po rozwinięciu wyników w konsoli otrzymasz następujące informacje:

console.log (nazwy)

zwróć uwagę na ostatnią właściwość – __proto__? Spróbuj go rozwinąć:

właściwość __proto__ nazw

zobaczysz zestaw właściwości pod Object konstruktor. Wszystkie te właściwości pochodzą z globalnego prototypu Object. Jeśli przyjrzysz się bliżej, zauważysz również nasz ukryty hasOwnProperty .

innymi słowy, wszystkie obiekty mają dostęp do prototypuObject. Nie posiadają tych właściwości, ale mają dostęp do właściwości w prototypie.

właściwość __proto__

wskazuje obiekt, który jest używany jako prototyp.

jest to właściwość dla każdego obiektu, który daje mu dostęp do właściwościObject prototype.

każdy obiekt posiada domyślnie tę właściwość, która odnosi się doObject Protoype, chyba że ustawiono inaczej (tzn. gdy__proto__ jest skierowany na inny prototyp).

Modyfikowanie właściwości __proto__

Ta właściwość może być zmodyfikowana przez wyraźne stwierdzenie, że powinna odnosić się do innego prototypu. Do tego celu służą następujące metody:

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);

w konsoli masz to, co:

konsola.log (bingo)

zwróć uwagę na__proto__ właściwość ispeak metodę?

Object.create używa argumentu przekazanego do niego, aby stać się prototypem.

nowe słowo kluczowe

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__ właściwość jest skierowana doDogObject’s prototype. Pamiętaj jednak ,żeDogObject’s prototype jest obiektem (parą kluczy i wartości), dlatego posiada również__proto__ właściwość, która odnosi się do globalnegoObject protoype.

technika ta nazywana jest prototypowym łańcuchem.

zauważ, że: podejścienew robi to samo coObject.create(), ale tylko ułatwia, ponieważ robi pewne rzeczy automatycznie dla ciebie.

I tak dalej…

każdy obiekt w Javascript ma domyślnie dostęp do prototypuObject. Jeśli skonfigurowano do używania innego prototypu, powiedzmy prototype2, wtedy prototype2 będzie miał również dostęp do prototypu obiektu domyślnie, i tak dalej.

kombinacja obiekt + funkcja

prawdopodobnie jesteś zdezorientowany faktem, żeDogObject jest funkcją (function DogObject(){}) I ma właściwości dostępne z notacją kropkową. Jest to określane jako kombinacja obiektów funkcyjnych.

gdy funkcje są zadeklarowane, domyślnie są im przypisane wiele właściwości. Pamiętaj, że funkcje są również obiektami w typach danych JavaScript.

teraz, Klasa

JavaScript wprowadziłaclass słowo kluczowe w ECMAScript 2015. To sprawia, że JavaScript wydaje się językiem OOP. Ale to tylko cukier syntatyczny nad istniejącą techniką prototypowania. Kontynuuje swoje prototypowanie w tle, ale sprawia, że zewnętrzne ciało wygląda jak OOP. Przyjrzymy się teraz, jak to możliwe.

poniższy przykład jest ogólnym zastosowaniemclass w 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);

jest to wynik w konsoli:

konsola.log (bingo)

__proto__ odwołuje się doAnimals prototyp (który z kolei odwołuje się doObject prototyp).

z tego widać, że konstruktor definiuje główne cechy, podczas gdy wszystko poza konstruktorem (sing() Idance()) są dodatkowymi cechami (prototypami).

w tle, używając podejścia ze słowem kluczowym new, powyższe przekłada się na:

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");

podklasa

jest to funkcja w OOP, gdzie klasa dziedziczy funkcje z klasy nadrzędnej, ale posiada dodatkowe funkcje, których rodzic nie ma.

na przykład, powiedzmy, że chcesz utworzyć klasę kotów. Zamiast tworzyć klasę od zera – podając na nowo nazwę, wiek i właściwości gatunku, dziedziczysz te właściwości z macierzystej klasy zwierząt.

Ta klasa kotów może mieć wtedy dodatkowe właściwości, takie jak kolor wąsów.

zobaczmy, jak podklasy są wykonane zclass.

tutaj potrzebujemy rodzica, od którego dziedziczy podklasa. Sprawdź następujący kod:

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");

dzięki powyższemu otrzymujemy następujące wyjścia:

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

po zalogowaniu zawartości Clary w konsoli mamy:

konsola.log(clara)

zauważysz, że clara ma __proto__ właściwość, która odwołuje się do konstruktora Cats I uzyskuje dostęp do whiskers() metoda. Ta__proto__ właściwość ma również__proto__ właściwość, która odwołuje się do konstruktoraAnimals, uzyskując w ten sposób dostęp dosing() Idance()name Iage są właściwościami, które istnieją na każdym obiekcie utworzonym z tego obiektu.

korzystając z metodyObject.create, powyższe przekłada się na:

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 jest metodą, która przyjmuje dwa argumenty – obiekt (pierwszy argument) i żądany prototyp (drugi argument).

z powyższego,Animals funkcja zwraca obiekt zanimalConstructor jako prototyp. FunkcjaCats zwraca obiekt zcatConstructor jako prototyp. catConstructor z kolei otrzymuje prototypanimalConstructor.

dlatego zwykłe zwierzęta mają dostęp tylko doanimalConstructor, ale koty mają dostęp docatConstructor IanimalConstructor.

zakończenie

JavaScript wykorzystuje swoją prototypową naturę, aby powitać programistów OOP w swoim ekosystemie. Zapewnia również łatwe sposoby tworzenia prototypów i organizowania powiązanych danych.

języki True OOP nie wykonują prototypów w tle – po prostu zwróć na to uwagę.

Wielkie podziękowania dla Will Sentance ’ s course on Frontend Masters-JavaScript: the Hard Parts of Object Oriented JavaScript. Nauczyłem się wszystkiego, co widzisz w tym artykule (plus trochę dodatkowych badań) z jego kursu. Powinieneś to sprawdzić.

możesz do mnie napisać na Twitterze na iamdillion w razie jakichkolwiek pytań lub uwag.

dzięki za przeczytanie:)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.