Demistifikuokime „JavaScript“ „naują“ raktinį žodį

Savaitgalį užbaigiau „Will Sentance“ „JavaScript: The Hard Parts“. Galbūt tai neatrodo pats šlovingiausias savaitgalio praleidimo būdas, bet iš tikrųjų man buvo gana smagu ir atsipalaiduoti baigiant kursą. Tai palietė funkcinį programavimą, aukštesnio lygio funkcijas, uždarymus ir asinchroninį „JavaScript“.

Man svarbiausia buvo tai, kaip jis išplėtojo „JavaScript“ požiūrį į objektinį programavimą (OOP) ir atskleidė naujojo operatoriaus magiją . Dabar puikiai suprantu, kas vyksta po gaubtu, kai naudojamas naujas operatorius.

Objektinis programavimas „ JavaScript“

Į objektą orientuotas programavimas (OOP) yra programavimo paradigma, pagrįsta „objektų“ sąvoka. Duomenys ir funkcijos (atributai ir metodai) yra susieti su objektu.

„JavaScript“ objektas yra raktų ir verčių porų rinkinys. Šios raktų ir verčių poros yra objekto savybės. Nuosavybė gali būti masyvas, funkcija, pats objektas arba bet koks primityvus duomenų tipas, pavyzdžiui, eilutės ar sveiki skaičiai.

Kokius „JavaScript“ įrankių rinkinio objektus galime kurti?

Tarkime, kad mes kuriame vartotojus ką tik sukurtame žaidime. Kaip mes saugotume išsamią vartotojo informaciją, pvz., Jų vardus, taškus, ir įgyvendintume tokius metodus kaip taškų prieaugis? Čia yra dvi pagrindinio objekto kūrimo galimybės.

1 variantas - objekto pažodinis žymėjimas

let user1 = { name: "Taylor", points: 5, increment: function() { user1.points++; } };

„JavaScript“ objekto literalas yra vardų ir reikšmių porų, suvyniotų į garbanotas petnešas, sąrašas. Aukščiau pateiktame pavyzdyje sukurtas objektas „user1“ ir jame saugomi susieti duomenys.

2 variantas - Object.create ()

Object.create(proto, [ propertiesObject ])

Object.create metodai priima du argumentus:

  1. proto: objektas, kuris turėtų būti naujai sukurto objekto prototipas. Tai turi būti objektas arba nulis.
  2. propertiesObject: naujo objekto savybės. Šis argumentas yra neprivalomas.

Iš esmės jūs perduodate Object.createobjektą, iš kurio norite paveldėti, ir jis grąžina naują objektą, paveldimą iš objekto, kurį į jį perėmėte.

let user2 = Object.create(null); user2.name = "Cam"; user2.points = 8; user2.increment = function() { user2.points++; }

Pagrindinės aukščiau nurodytos objekto kūrimo parinktys kartojasi. Tai reikalauja, kad kiekvienas būtų sukurtas rankiniu būdu.

Kaip tai įveikti?

Sprendimai

1 sprendimas - sukurkite objektus naudodami funkciją

Paprastas sprendimas yra parašyti funkciją naujų vartotojų sukūrimui.

function createUser(name, points) { let newUser = {}; newUser.name = name; newUser.points = points; newUser.increment = function() { newUser.points++; }; return newUser; }

Norėdami sukurti vartotoją, dabar funkcijos parametruose turėtumėte įvesti informaciją.

let user1 = createUser("Bob", 5); user1.increment();

Tačiau aukščiau pateiktame pavyzdyje prieaugio funkcija yra tik pradinės prieaugio funkcijos kopija. Tai nėra geras būdas parašyti kodą, nes bet kokius galimus funkcijos pakeitimus reikės atlikti rankiniu būdu kiekvienam objektui.

2 sprendimas - naudokite „JavaScript“ prototipinį pobūdį

Skirtingai nuo objektyvių kalbų, tokių kaip Python ir Java, „JavaScript“ neturi klasių. Paveldėjimui naudojama prototipų ir grandinių grandinės samprata.

Kai kuriate naują masyvą, jūs automatiškai turi prieigą prie įmontuotą metodais, tokiais kaip Array.join, Array.sortir Array.filter. Taip yra dėl to, kad masyvo objektai paveldi ypatybes iš „Array.prototype“.

Kiekviena „JavaScript“ funkcija turi prototipo ypatybę, kuri pagal numatytuosius nustatymus yra tuščia. Prie šios prototipo ypatybės galite pridėti funkcijas, ir šioje formoje jis žinomas kaip metodas. Vykdant paveldėtą funkciją, šios vertės reikšmė yra paveldimas objektas.

function createUser(name, points) { let newUser = Object.create(userFunction); newUser.name = name; newUser.points = points; return newUser; } let userFunction = { increment: function() {this.points++}; login: function() {console.log("Please login.")}; } let user1 = createUser("Bob", 5); user1.increment();

Kai user1objektas buvo sukurtas, susiformavo grandinės ryšio su „userFunction“ prototipas.

Kai user1.increment() yra skambučių krūvelėje, vertėjas ieškos vartotojo1 pasaulinėje atmintyje. Tada jis ieškos prieaugio funkcijos, bet jos neras. Vertėjas pažvelgs į kitą objektą prototipo grandinėje ir ten ras prieaugio funkciją.

3 sprendimas - naujas ir šis raktinis žodis

Thenaujas operatorius naudojamas sukurti objekto, turinčio konstruktoriaus funkciją, egzempliorių.

Kai konstruktoriaus funkciją iškviečiame nauju, mes automatizuojame šiuos veiksmus:

  • Sukuriamas naujas objektas
  • Jis prisijungia thisprie objekto
  • Konstruktoriaus funkcijos prototipas tampa naujo objekto savybe __proto__
  • Jis grąžina objektą iš funkcijos

Tai yra fantastika, nes dėl automatikos gaunamas mažiau pasikartojantis kodas!

function User(name, points) { this.name = name; this.points = points; } User.prototype.increment = function(){ this.points++; } User.prototype.login = function() { console.log(“Please login.”) } let user1 = new User(“Dylan”, 6); user1.increment();

Naudojant prototipo modelį, kiekvienas metodas ir savybė pridedami tiesiai prie objekto prototipo.

Vertėjas eis aukštyn prototipine grandine ir suras prieaugio funkciją po vartotojo prototipo savybe, kuris pats yra objektas, kuriame yra informacija. Atminkite - visos „JavaScript“ funkcijos taip pat yra objektai . Dabar, kai vertėjas rado tai, ko jam reikia, jis gali sukurti naują vietinį vykdymo kontekstą user1.increment().

Šoninė pastaba: skirtumas tarp __proto__ ir prototipo

Jei jau painotės dėl __proto__ ir prototipo, nesijaudinkite! Jūs esate toli gražu ne vienintelis dėl to supainiotas.

Prototipas yra konstruktoriaus funkcijos savybė, kuri lemia tai, kas taps sukonstruoto objekto savybe __proto__.

Taigi, __proto__ yra sukurta nuoroda, kuri yra žinoma kaip grandinės ryšio prototipas.

4 sprendimas - ES6 sintaksinis cukrus

Kitos kalbos leidžia mums rašyti bendrus metodus pačiame objekto „konstruktoriuje“. „ECMAScript6“ pristatė klasės raktinį žodį, leidžiantį mums rašyti klases, panašias į įprastas kitų klasikinių kalbų klases. Iš tikrųjų tai yra sintaksinis cukrus, palyginti su „JavaScript“ prototipiniu elgesiu.

class User { constructor(name, points) { this.name = name; this.points = points; } increment () { this.points++; } login () { console.log("Please login.") } } let user1 = new User("John", 12); user1.increment();

3 sprendime susiję metodai buvo tiksliai įgyvendinti naudojant User.prototype.functionName. Šiuo sprendimu pasiekiami tie patys rezultatai, tačiau sintaksė atrodo švaresnė.

Išvada

Dabar mes sužinojome daugiau apie įvairias „JavaScript“ galimybes, kad galėtume kurti objektus. Nors klasės deklaracijos irnaujus operatorius naudoti yra gana paprasta, svarbu suprasti, kas yra automatizuota.

Apibendrinant, šie veiksmai yra automatizuoti, kai konstruktoriaus funkcija iškviečiama nauja :

  • Sukuriamas naujas objektas
  • Jis prisijungia thisprie objekto
  • Konstruktoriaus funkcijos prototipas tampa naujo objekto savybe __proto__
  • Jis grąžina objektą iš funkcijos

Ačiū, kad perskaitėte mano straipsnį, ir plokite, jei jums patiko! Peržiūrėkite kitus mano straipsnius, pvz., Kaip sukūriau savo „Pomodoro Clock“ programą, ir pamokas, kurias išmokau kelyje.