在 JavaScript ES6 中使用对象作为索引数组是一个好的模式吗?

Is it a good pattern to use an Object as an indexed array in JavaScript ES6?

这个模式我见过很多次了:

var messages = {};

function addMessage(newMessage) {
  messages[newMessage.id] = newMessage;
}

function numUnread() {
  var unread = 0;
  for (var id in messages) {
    if (messages[id]) {
      unread++;
    }
  }
  return unread;
}

将 JavaScript 对象用作关联数组的一个问题是无法使用方便的数组方法,如 lengthfiltermap

那么,用数组代替会更好吗?

let messages = [];

function addMessage(newMessage) {
  const newMessages = messages
      .filter(msg => msg.id !== newMessage.id)
      .push(newMessage);
  messages = newMessages;
}

function numUnread() {
  return messages.filter(msg => !msg.isRead).length();
}

使用对象并没有什么错,你只需要确保你的键不会与 Object.prototype 方法冲突。如果它们是数字 ID,这很容易。

然而,在 ES6 中,你应该只使用 Map。这也使您可以轻松获得尺寸。不幸的是,它还没有类似数组的辅助方法,但它确实可以很好地与迭代器配合使用。

const messages = new Map();

function addMessage(newMessage) {
  messages.set(newMessage.id, newMessage);
}

function numUnread() {
  let unread = 0;
  for (let {isRead} of messages.values())
    if (!isRead)
      unread++;
  return unread;
}