JavaScript objekti, uglate zagrade i algoritmi

Jedan od najsnažnijih aspekata JavaScript-a je mogućnost dinamičkog upućivanja na svojstva objekata. U ovom ćemo članku pogledati kako to funkcionira i koje bi nam prednosti to moglo dati. Kratko ćemo pogledati neke od podatkovnih struktura koje se koriste u računalnim znanostima. Uz to ćemo pogledati nešto što se naziva Big O notacija koja se koristi za opisivanje izvedbe algoritma.

Uvod u predmete

Počnimo s izradom jednostavnog predmeta koji predstavlja automobil. Svaki objekt ima nešto što se zove properties. Svojstvo je varijabla koja pripada objektu. Naš automobil objekt će imati tri svojstva: make, modeli color.

Pogledajmo kako bi to moglo izgledati:

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

Pomoću točkastih notacija možemo se pozvati na pojedina svojstva predmeta. Primjerice, ako smo željeli saznati kakva je boja našeg automobila, možemo koristiti ovakvu točku car.color.

Mogli bismo ga čak i objaviti koristeći console.log:

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

Drugi način upućivanja na svojstvo je korištenje oznake u zagradama:

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

U gornjem primjeru koristimo ime svojstva kao niz unutar uglatih zagrada da bismo dobili vrijednost koja odgovara tom imenu svojstva. Korisna stvar kod notacije u kvadratnim zagradama je ta što također možemo koristiti varijable za dinamičko dobivanje svojstava.

Odnosno, umjesto da teško kodiramo određeno ime svojstva, možemo ga odrediti kao niz u varijabli:

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

Korištenje dinamičkog pretraživanja s oznakom uglastih zagrada

Pogledajmo primjer gdje to možemo koristiti. Recimo da vodimo restoran i želimo biti u mogućnosti dobiti cijene stavki na našem jelovniku. Jedan od načina za to je korištenje if/elseizjava.

Napišimo funkciju koja će prihvatiti naziv predmeta i vratiti cijenu:

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

Iako gornji pristup djeluje, nije idealan. Izbornik smo čvrsto kodirali u našem kodu. Ako se naš izbornik promijeni, morat ćemo prepisati naš kôd i preraspodijeliti ga. Osim toga, mogli bismo imati dugački izbornik i kad bi morao pisati sav ovaj kod, bilo bi glomazno.

Bolji pristup bio bi razdvajanje podataka i logike. Podaci će sadržavati naš izbornik, a logika će tražiti cijene s tog izbornika.

Možemo predstaviti menuobjekt kao objekt u kojem naziv svojstva, poznat i kao ključ, odgovara vrijednosti.

U ovom slučaju ključ će biti naziv artikla, a vrijednost cijena artikla:

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

Korištenjem oznake u zagradama možemo stvoriti funkciju koja će prihvatiti dva argumenta:

  • objekt izbornika
  • niz s nazivom stavke

i vratite cijenu tog predmeta:

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

Uredna stvar kod ovog pristupa je da smo odvojili svoje podatke od naše logike. U ovom primjeru podaci žive u našem kodu, ali jednako lako mogu doći iz baze podataka ili API-ja. Više nije usko povezan s našom logikom pretraživanja koja naziv predmeta pretvara u cijenu predmeta.

Strukture podataka i algoritmi

Karta u terminima informatike je struktura podataka koja je skup parova ključ / vrijednost gdje se svaki ključ preslikava na odgovarajuću vrijednost. Pomoću nje možemo potražiti vrijednost koja odgovara određenom ključu. To je ono što radimo u prethodnom primjeru. Imamo ključ koji je naziv stavke i možemo potražiti odgovarajuću cijenu te stavke pomoću našeg objekta iz izbornika. Koristimo objekt za implementaciju strukture podataka karte.

Pogledajmo primjer zašto bismo možda željeli koristiti kartu. Recimo da vodimo knjižaru i imamo popis knjiga. Svaka knjiga ima jedinstveni identifikator pod nazivom Međunarodni standardni broj knjige (ISBN), koji je 13-znamenkasti broj. Svoje knjige pohranjujemo u niz i želimo ih potražiti pomoću ISBN-a.

Jedan od načina je premotavanjem niza, provjerom ISBN vrijednosti svake knjige i podudara li se s vraćanjem:

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

To dobro funkcionira u ovom primjeru, jer imamo samo tri knjige (to je mala knjižara). Međutim, da smo Amazon, ponavljanje milijuna knjiga moglo bi biti vrlo sporo i računski skupo.

Oznaka Big O koristi se u računalnim znanostima za opisivanje izvedbe algoritma. Na primjer, ako je n broj knjiga u našoj zbirci, trošak korištenja iteracije za traženje knjige u najgorem slučaju (knjiga koju tražimo posljednja je na popisu) bit će O (n) . To znači da će se, ako se broj knjiga u našoj zbirci udvostruči, udvostručiti i troškovi pronalaska knjige pomoću iteracije.

Pogledajmo kako svoj algoritam možemo učiniti učinkovitijim koristeći drugu strukturu podataka.

Kao što je već rečeno, karta se može koristiti za traženje vrijednosti koja odgovara ključu. Naše podatke možemo strukturirati kao mapu umjesto niza pomoću objekta.

Ključ će biti ISBN, a vrijednost odgovarajući objekt knjige:

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

Umjesto korištenja iteracije, sada možemo koristiti jednostavno pretraživanje karte prema ISBN-u da bismo dobili svoju vrijednost. Više ne trebamo provjeravati vrijednost ISBN za svaki objekt. Vrijednost dobivamo izravno s karte pomoću ključa.

Što se tiče izvedbe, pretraživanje mape pružit će ogroman napredak u odnosu na iteraciju. To je zato što traženje karte ima konstantne troškove u smislu izračuna. To se može napisati pomoću oznake Big O kao O (1) . Nije važno imamo li tri ili tri milijuna knjiga, knjigu koju želimo možemo dobiti jednako brzo izvršavanjem pretraživanja karte pomoću ISBN ključa.

Rekapitulacija

  • 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.

Want to learn how to write web applications using JavaScript? I run Constructor Labs, a 12 week JavaScript coding bootcamp in London. The technologies taught include HMTL, CSS, JavaScript, React, Redux, Node and Postgres. Everything you need to create an entire web app from scratch and get your first job in the industry. Fees are £3,000 and next cohort starts on 29th May. Applications are open now.