Demisztifikáljuk a JavaScript „új” kulcsszavát

A hétvégén elkészítettem Will Sentance JavaScript: A kemény alkatrészeket. Lehet, hogy nem úgy hangzik, mint egy hétvége legdicsőbb módja, de valójában nagyon szórakoztatónak és pihentetőnek tartottam a tanfolyam elvégzését. Érintette a funkcionális programozást, a magasabb rendű funkciókat, a bezárásokat és az aszinkron JavaScript-et.

Számomra a kurzus fénypontja az volt, hogy kibővítette az objektumorientált programozás (OOP) JavaScript-megközelítéseit, és demisztifikálta az új operátor varázsát . Most már jól átlátom, mi történik a motorháztető alatt, amikor az új kezelőt használják.

Objektumorientált programozás JavaScript-ben

Az objektumorientált programozás (OOP) egy programozási paradigma, amely az „objektumok” fogalmán alapszik. Az adatok és a függvények (attribútumok és módszerek) egy objektumon belül vannak kötegelve.

A JavaScript egyik objektuma kulcs-érték párok gyűjteménye. Ezek a kulcs-érték párok az objektum tulajdonságai. A tulajdonság lehet tömb, függvény, maga az objektum vagy bármilyen primitív adattípus, például karakterlánc vagy egész szám.

Milyen technikák vannak a JavaScript eszköztárunkban az objektumok létrehozásához?

Tegyük fel, hogy egy általunk tervezett játékban hozunk létre felhasználókat. Hogyan tárolnánk a felhasználó adatait, például nevüket, pontjaikat, és megvalósítanánk olyan módszereket, mint a pontok növekedése? Az alapobjektum-létrehozásnak két lehetősége van.

1. opció - Objektum betű szerinti jelölés

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

A JavaScript objektum literál a név-érték párok listája, göndör zárójelekbe csomagolva. A fenti példában a 'user1' objektum jön létre, és a kapcsolódó adatok benne vannak tárolva.

2. lehetőség - Object.create ()

Object.create(proto, [ propertiesObject ])

Object.create módszerek két érvet fogadnak el:

  1. proto: az objektum, amelynek az újonnan létrehozott objektum prototípusának kell lennie. Ennek objektumnak vagy nullnak kell lennie.
  2. propertiesObject: az új objektum tulajdonságai. Ez az érvelés nem kötelező.

Alapvetően átmegy egy Object.createolyan objektumba, amelytől örökölni szeretnél, és ez egy új objektumot ad vissza, amely örököl a belőle átadott objektumtól.

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

A fenti alapvető objektum létrehozási lehetőségek ismétlődnek. Megköveteli, hogy mindegyiket manuálisan hozzák létre.

Hogyan tudjuk ezt legyőzni?

Megoldások

1. megoldás - Objektumok létrehozása egy függvény használatával

Egyszerű megoldás egy függvény megírása új felhasználók létrehozásához.

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

Felhasználó létrehozásához meg kell adnia az információkat a függvény paramétereiben.

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

A fenti példában szereplő növekményfüggvény azonban csak az eredeti növekményfüggvény másolata. Ez nem jó módszer a kód megírásához, mivel a funkció esetleges változtatásait manuálisan kell elvégezni az egyes objektumokhoz.

2. megoldás - Használja a JavaScript prototípus jellegét

Az olyan objektumorientált nyelvektől, mint a Python és a Java, a JavaScript nem rendelkezik osztályokkal. A prototípusok és a prototípus láncolás fogalmát használja az örökléshez.

Amikor létrehoz egy új tömböt, akkor automatikusan hozzáférhet beépített módszerekkel, például Array.join, Array.sortés Array.filter. Ez annak a ténynek köszönhető, hogy a tömb objektumok tulajdonságokat örökölnek az Array.prototype-ból.

Minden JavaScript-funkciónak van egy prototípus-tulajdonsága, amely alapértelmezés szerint üres. Funkciókat hozzáadhat ehhez a prototípus tulajdonsághoz, és ebben a formában ez módszerként ismert. Egy öröklött függvény végrehajtásakor ennek értéke az öröklődő objektumra mutat.

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

Az user1objektum létrehozásakor kialakult egy prototípus lánckötés a userFunction-szal.

Amikor user1.increment() a hívásveremben van, az értelmező a user1-et keresi a globális memóriában. Ezután megkeresi az inkrement függvényt, de nem fogja megtalálni. A tolmács megkeresi a következő objektumot a prototípusláncban, és megtalálja az inkrement függvényt.

3. megoldás - új és ez a kulcsszó

Aúj operátor segítségével létrehozható egy objektum példánya, amelynek konstruktor funkciója van.

Amikor újnak hívjuk a konstruktor függvényt, akkor a következő műveleteket automatizáljuk:

  • Új objektum jön létre
  • Megköti thisaz objektumot
  • A konstruktor függvény prototípus objektuma az új objektum __proto__ tulajdonságává válik
  • Visszaadja az objektumot a függvényből

Ez fantasztikus, mert az automatizálás kevesebb ismétlődő kódot eredményez!

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

A prototípus minta használatával minden módszer és tulajdonság hozzáadódik közvetlenül az objektum prototípusához.

Az értelmező felmegy a prototípus láncra, és a Felhasználó prototípus tulajdonságánál megtalálja az inkrement függvényt, amely maga is egy objektum, benne a benne lévő információkkal. Ne feledje - A JavaScript összes funkciója szintén objektum . Most, hogy a tolmács megtalálta, amire szüksége van, létrehozhat egy új futtatható helyi végrehajtási kontextust user1.increment().

Mellékjegyzet: Különbség a __proto__ és a prototípus között

Ha már összezavarodik a __proto__ és a prototípus miatt, ne aggódjon! Ön messze nem az egyetlen, akit ebben zavar.

A prototípus a konstruktor függvény azon tulajdonsága, amely meghatározza, hogy mi lesz a __proto__ tulajdonság a felépített objektumon.

Tehát a __proto__ a létrehozott referencia, és ez a hivatkozás prototípus lánckötésként ismert.

4. megoldás - ES6 „szintaktikus cukor”

Más nyelvek lehetővé teszik számunkra, hogy megírjuk megosztott módszereinket magában a „konstruktor” objektumban. Az ECMAScript6 bevezette az osztály kulcsszót, amely lehetővé teszi számunkra, hogy olyan osztályokat írjunk, amelyek hasonlítanak más klasszikus nyelv normál osztályaihoz. A valóságban szintaktikus cukor a JavaScript prototípusos viselkedése felett.

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

A 3. megoldásban a kapcsolódó módszereket pontosan megvalósítottuk User.prototype.functionName. Ebben a megoldásban ugyanazok az eredmények érhetők el, de a szintaxis tisztábbnak tűnik.

Következtetés

Most többet megtudtunk az objektumok létrehozásához a JavaScript különböző lehetőségeiről. Míg az osztálynyilatkozatok és aúj operátor viszonylag könnyen használható, fontos megérteni, mi automatizált.

Összegezve a következő műveletek automatizált, amikor a kivitelező függvény hívására új :

  • Új objektum jön létre
  • Megköti thisaz objektumot
  • A konstruktor függvény prototípus objektuma az új objektum __proto__ tulajdonságává válik
  • Visszaadja az objektumot a függvényből

Thanks for reading my article, and clap if you liked it! Check out my other articles like How I built my Pomodoro Clock app, and the lessons I learned along the way.