JavaScriptオブジェクト、角括弧、およびアルゴリズム

JavaScriptの最も強力な側面の1つは、オブジェクトのプロパティを動的に参照できることです。この記事では、これがどのように機能し、これがどのような利点をもたらすかを見ていきます。コンピュータサイエンスで使用されるデータ構造のいくつかを簡単に見ていきます。さらに、アルゴリズムのパフォーマンスを説明するために使用されるBigO表記と呼ばれるものを見ていきます。

オブジェクトの紹介

車を表す単純なオブジェクトを作成することから始めましょう。各オブジェクトには、と呼ばれるものがありpropertiesます。プロパティは、オブジェクトに属する変数です。車のオブジェクトには、、、の3つのプロパティmakemodelありcolorます。

それがどのように見えるか見てみましょう:

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

ドット表記を使用して、オブジェクトの個々のプロパティを参照できます。たとえば、車の色を知りたい場合は、次のようなドット表記を使用できますcar.color

を使用して出力することもできますconsole.log

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

プロパティを参照する別の方法は、角括弧表記を使用することです。

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

上記の例では、プロパティ名を角かっこ内の文字列として使用して、そのプロパティ名に対応する値を取得します。角括弧表記の便利な点は、変数を使用してプロパティを動的に取得できることです。

つまり、特定のプロパティ名をハードコーディングするのではなく、変数の文字列として指定できます。

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

角括弧表記による動的ルックアップの使用

これを使用できる例を見てみましょう。たとえば、レストランを経営していて、メニューの商品の価格を取得できるようにしたいとします。これを行う1つの方法は、if/elseステートメントを使用することです。

アイテム名を受け入れて価格を返す関数を書いてみましょう。

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

上記のアプローチは機能しますが、理想的ではありません。メニューをコードにハードコーディングしました。メニューが変更された場合は、コードを書き直して再デプロイする必要があります。さらに、メニューが長くなる可能性があり、このコードをすべて記述しなければならないのは面倒です。

より良いアプローチは、データとロジックを分離することです。データにはメニューが含まれ、ロジックはそのメニューから価格を検索します。

menuキーとも呼ばれるプロパティ名が値に対応するオブジェクトとして、を表すことができます。

この場合、キーはアイテム名になり、値はアイテム価格になります。

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

角括弧表記を使用して、2つの引数を受け入れる関数を作成できます。

  • メニューオブジェクト
  • アイテム名の文字列

そのアイテムの価格を返します。

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

このアプローチの優れた点は、データをロジックから分離したことです。この例では、データはコード内にありますが、データベースまたはAPIから簡単に取得できます。これは、アイテム名をアイテム価格に変換するルックアップロジックと緊密に結合されなくなりました。

データ構造とアルゴリズム

コンピュータサイエンス用語のマップは、各キーが対応する値にマップされるキーと値のペアのコレクションであるデータ構造です。これを使用して、特定のキーに対応する値を探すことができます。これは、前の例で行っていることです。アイテム名であるキーがあり、メニューオブジェクトを使用してそのアイテムの対応する価格を検索できます。オブジェクトを使用して、マップデータ構造を実装しています。

マップを使用する理由の例を見てみましょう。書店を経営していて、本のリストがあるとしましょう。各本には、13桁の番号である国際標準図書番号(ISBN)と呼ばれる一意の識別子があります。私たちは本を配列で保存し、ISBNを使用してそれらを検索できるようにしたいと考えています。

これを行う1つの方法は、配列をループして、各本のISBN値をチェックし、それが一致するかどうかを返すことです。

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.

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.