(譯) javascript中的物件,方括號和演算法

飛翔的大象發表於2019-03-08

JavaScript最強大的一個方面是能夠動態引用物件的屬性,在本文中,我們將瞭解他的工作原理以及它帶給我們的好處。我們將快速瀏覽一下電腦科學中使用的一些資料結構。此外,我們將研究一種名為大O表示法的東西,用於描述演算法的效能。

物件簡介

讓我們從建立一個名為car的物件開始,每一個物件都有一個叫屬性的東西。屬性是屬於一個物件的變數。car物件將有三個屬性:make,model和color。

讓我們看看它的樣子:

const car = {
  make: 'Ford',
  model: 'Fiesta',
  color: 'Red'
};
複製程式碼

我們可以使用點表示法來引用物件的屬性。例如,如果我們想要找出car的顏色,我們可以使用點表示法,就像這樣: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
複製程式碼

使用帶方括號表示法的動態查詢

讓我們看一個我們可以使用它的例子。假設我們經營一家餐館,我們希望能夠在選單上獲得商品的價格。這樣做的一種方法是使用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;
  }
}
複製程式碼

雖然上面的方法有效,但是他不是理想的。在我們的code中有選單的硬編碼。現在如果我們的選單改變了,我們不得不重寫程式碼並且重新部署。此外,我們可以有一個很長的選單,不得不寫所有這些程式碼將是繁瑣的。

更好的方法是分離我們的資料和邏輯。資料將包含我們的選單,邏輯將從該選單中查詢價格。

我們可以將選單表示為物件,其中屬性名稱(也稱為鍵)對應於值。

在這種情況下,鍵將是專案名稱,值將是專案價格:

const menu = {
  burger: 10,
  fries: 3,
  coleslaw: 4,
  coke: 2,
  beer: 5
};
複製程式碼

使用方括號表示法,我們可以建立一個接受兩個引數的函式:選單物件和一個菜名並且返回菜品的價格:

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。它不再與我們的查詢邏輯緊密耦合,後者將菜品名稱轉換為菜品價格。

資料結構和演算法

電腦科學術語中的map是一種資料結構,它是鍵/值對的集合,其中每個鍵對映到相應的值。我們可以使用它來查詢與特定鍵對應的值。 這就是我們在前面的例子中所做的。我們有一個菜品的名稱,我們可以使用選單物件查詢該專案的相應價格。我們正在使用一個物件來實現一個map資料結構。

讓我們看看為什麼我們可能想要使用Map。 假設我們經營一家書店,並有一份書籍清單。 每本書都有一個名為國際標準書號(ISBN)的唯一識別符號,這是一個13位數字。 我們將圖書儲存在一個陣列中,希望能夠使用ISBN查詢它們。

一種方法是迴圈遍歷陣列,檢查每本書的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);
複製程式碼

這個例子很好用,因為我們只有三本書(這是一個小書店)。但是,如果我們是亞馬遜,那麼迭代數以百萬計的書籍可能會非常慢並且計算成本也很高。

電腦科學中使用大O表示法來描述演算法的效能。例如,如果n是我們集合中的書籍數量,那麼在最壞的情況下使用迭代來查詢書籍的成本(我們要查詢的書是列表中的最後一本)將是O(n)。這意味著如果我們集合中的書籍數量增加一倍,使用迭代查詢書籍的成本也會翻倍。

讓我們看看如何通過使用不同的資料結構使我們的演算法更有效。

如上所述,可以使用對映來查詢與鍵對應的值。 我們可以使用物件將資料結構化為map(這裡指物件)而不是陣列。

鍵將是ISBN,值將是相應的書物件:

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);
複製程式碼

我們現在可以使用ISBN的簡單地圖查詢來獲取我們的價值,而不是使用迭代。我們不再需要檢查每個物件的ISBN值。 我們使用key直接從地圖獲取值。

在效能方面,地圖查詢將提供相對於迭代的巨大改進。 這是因為地圖查詢在計算方面具有不變的成本。 這可以使用大O表示法寫為O(1)。如果我們有三三百萬冊書籍沒關係,我們可以通過使用ISBN鍵進行地圖查詢來快速獲得我們想要的書。

總結

  • 我們可以使用點表示法和方括號表示法訪問物件屬性的值
  • 我們學習瞭如何通過使用帶方括號表示法的變數來動態查詢屬性值
  • 我們還了解到,map資料結構將鍵對映到值。 我們可以使用鍵直接在我們使用物件實現的map中查詢值。
  • 我們初看了如何使用大O表示法描述演算法效能。此外,我們還看到了如何通過將物件陣列轉換為map並使用直接查詢而不是迭代來提高搜尋效能。

ps: hardcode真的是很硬...

相關文章