JavaScript-objekter, firkantede parenteser og algoritmer

Et af de mest magtfulde aspekter af JavaScript er at være i stand til dynamisk at henvise til objektegenskaber. I denne artikel vil vi se på, hvordan dette fungerer, og hvilke fordele dette kan give os. Vi kigger hurtigt på nogle af datastrukturer, der anvendes i datalogi. Derudover vil vi se på noget kaldet Big O-notation, der bruges til at beskrive præstationen for en algoritme.

Objekter intro

Lad os begynde med at oprette et simpelt objekt, der repræsenterer en bil. Hver genstand har noget, der kaldes properties. En egenskab er en variabel, der hører til et objekt. Vores bil objekt vil have tre egenskaber: make, modelog color.

Lad os se, hvordan det kunne se ud:

const car = { make: 'Ford', model: 'Fiesta', color: 'Red'};

Vi kan henvise til individuelle egenskaber ved et objekt ved hjælp af punktnotation. For eksempel, hvis vi ønskede at finde ud af, hvad farven på vores bil er, kan vi bruge priknotation som denne car.color.

Vi kunne endda sende det ved hjælp af console.log:

console.log(car.color); //outputs: Red

En anden måde at henvise til en ejendom er ved at bruge firkantede parenteser:

console.log(car['color']); //outputs: Red

I ovenstående eksempel bruger vi egenskabsnavnet som en streng inden for firkantede parenteser for at få den værdi, der svarer til dette egenskabsnavn. Den nyttige ting ved firkantet parentesnotation er, at vi også kan bruge variabler til at få egenskaber dynamisk.

Det vil sige, i stedet for at hardcode et specifikt egenskabsnavn, kan vi specificere det som en streng i en variabel:

const propertyName = 'color';const console.log(car[propertyName]); //outputs: Red

Brug af dynamisk opslag med notation i firkantet parentes

Lad os se på et eksempel, hvor vi kan bruge dette. Lad os sige, at vi driver en restaurant, og vi vil være i stand til at få priserne på varer på vores menu. En måde at gøre dette på er at bruge if/elseudsagn.

Lad os skrive en funktion, der accepterer et varenavn og returnerer en pris:

function getPrice(itemName){ if(itemName === 'burger') { return 10; } else if(itemName === 'fries') { return 3; } else if(itemName === 'coleslaw') { return 4; } else if(itemName === 'coke') { return 2; } else if(itemName === 'beer') { return 5; }}

Mens ovenstående fremgangsmåde fungerer, er den ikke ideel. Vi har hardkodet menuen i vores kode. Hvis vores menu ændres, bliver vi nu nødt til at omskrive vores kode og omplacere den. Derudover kunne vi have en lang menu, og det skulle være besværligt at skulle skrive al denne kode.

En bedre tilgang ville være at adskille vores data og vores logik. Dataene indeholder vores menu, og logikken vil slå priser op fra den menu.

Vi kan repræsentere det menusom et objekt, hvor ejendomsnavnet, også kendt som en nøgle, svarer til en værdi.

I dette tilfælde vil nøglen være varens navn, og værdien er varens pris:

const menu = { burger: 10, fries: 3, coleslaw: 4, coke: 2, beer: 5};

Ved at bruge firkantede parenteser kan vi oprette en funktion, der accepterer to argumenter:

  • et menuobjekt
  • en streng med varenavn

og returner prisen på den vare:

const menu = { burger: 10, fries: 3, coleslaw: 4, coke: 2, beer: 5};
function getPrice(itemName, menu){ const itemPrice = menu[itemName]; return itemPrice;}
const priceOfBurger = getPrice('burger', menu);console.log(priceOfBurger); // outputs: 10

Det pæne ved denne tilgang er, at vi har adskilt vores data fra vores logik. I dette eksempel lever dataene i vores kode, men de kan lige så let komme fra en database eller API. Det er ikke længere tæt forbundet med vores opslagslogik, der konverterer varenavn til varepris.

Datastrukturer og algoritmer

Et kort i datalogi-termer er en datastruktur, som er en samling af nøgle / værdipar, hvor hver nøgle kortlægges til en tilsvarende værdi. Vi kan bruge den til at se en værdi, der svarer til en bestemt nøgle. Dette er hvad vi laver i det foregående eksempel. Vi har en nøgle, der er et varenavn, og vi kan slå den tilsvarende pris for denne vare op ved hjælp af vores menuobjekt. Vi bruger et objekt til at implementere en kortdatastruktur.

Lad os se på et eksempel på, hvorfor vi måske vil bruge et kort. Lad os sige, at vi driver en boghandel og har en liste over bøger. Hver bog har en unik identifikator kaldet International Standard Book Number (ISBN), som er et 13-cifret nummer. Vi gemmer vores bøger i en matrix og ønsker at være i stand til at slå dem op ved hjælp af ISBN.

En måde at gøre det på er ved at løkke over matrixen, kontrollere ISBN-værdien for hver bog og hvis den svarer til at returnere den:

const books = [{ isbn: '978-0099540946', author: 'Mikhail Bulgakov', title: 'Master and Margarita'}, { isbn: '978-0596517748', author: 'Douglas Crockford', title: 'JavaScript: The Good Parts'}, { isbn: '978-1593275846', author: 'Marijn Haverbeke', title: 'Eloquent JavaScript'}];
function getBookByIsbn(isbn, books){ for(let i = 0; i < books.length; i++){ if(books[i].isbn === isbn) { return books[i]; } }}
const myBook = getBookByIsbn('978-1593275846', books);

That works fine in this example since we only have three books (it’s a small book shop). However, if we were Amazon, iterating over millions of books could be very slow and computationally expensive.

Big O notation is used in Computer Science to describe the performance of an algorithm. For example if n is the number of books in our collection, the cost of using iteration to look up a book in the worst case scenario (the book we look for is last in the list) will be O(n). That means if the number of books in our collection doubles, the cost of finding a book using iteration will double as well.

Let’s take a look at how we can make our algorithm more efficient by using a different data structure.

As discussed, a map can be used to look up the value which corresponds to a key. We can structure our data as map instead of an array by using an object.

The key will be the ISBN and the value will be the corresponding book object:

const books = { '978-0099540946':{ isbn: '978-0099540946', author: 'Mikhail Bulgakov', title: 'Master and Margarita' }, '978-0596517748': { isbn: '978-0596517748', author: 'Douglas Crockford', title: 'JavaScript: The Good Parts' }, '978-1593275846': { isbn: '978-1593275846', author: 'Marijn Haverbeke', title: 'Eloquent JavaScript' }};
function getBookByIsbn(isbn, books){ return books[isbn];}
const myBook = getBookByIsbn('978-1593275846', books);

Instead of using iteration, we can now use a simple map lookup by ISBN to get our value. We no longer need to check the ISBN value for each object. We get the value directly from the map using the key.

In terms of performance, a map lookup will provide a huge improvement over iteration. This is because the map lookup has constant cost in terms of computation. This can be written using Big O notation as O(1). It does not matter if we have three or three million books, we can get the book we want just as fast by doing a map lookup using the ISBN key.

Recap

  • We have seen we can access the values of object properties using dot notation and square bracket notation
  • We learned how we can dynamically look up values of property by using variables with square bracket notation
  • We have also learned that a map datastructure maps keys to values. We can use keys to directly look up values in a map which we implement using an object.
  • We had a first glance at how algorithm performance is described using Big O notation. In addition, we saw how we can improve the performance of a search by converting an array of objects into a map and using direct lookup rather than iteration.

Want to test your new found skills? Try the Crash Override exercise on Codewars.

Vil du lære at skrive webapplikationer ved hjælp af JavaScript? Jeg kører Constructor Labs, en 12-ugers JavaScript-kodende bootcamp i London. De teknologier, der undervises, inkluderer HMTL , CSS , JavaScript , React , Redux , Node og Postgres . Alt hvad du behøver for at oprette en hel webapp fra bunden og få dit første job i branchen. Gebyrer er £ 3.000, og den næste kohorte starter den 29. maj. Ansøgninger er åbne nu.