Статьи

Несколько ролей JavaScript-объектов и массивов

И объекты, и массивы играют несколько ролей в JavaScript. Этот пост в блоге объясняет, каковы эти роли.

Объекты и массивы представляют собой двойные структуры данных

Объекты: записи против карт

Объект JavaScript представляет собой комбинацию двух структур данных: иногда он используется как запись, иногда как словарь.

  • Запись:

    • Фиксированная форма (ключи известны заранее)
    • Каждая запись (ключ, значение) имеет различное значение
    • Дословные имена: Используйте имена буквально. Пример: obj.key
  • Карта (словарь), от строк до произвольных значений:

    • Гибкая форма (ключи обычно неизвестны заранее)
    • Каждая запись (ключ, значение) имеет аналогичное значение
    • Вычисляемые имена: обычно существует один уровень косвенности, вы не используете имена напрямую. Пример: obj [mykey] (mykey — переменная, которая содержит фактический ключ)

Массивы: кортежи и списки

Подобно объектам, массивы представляют собой комбинацию двух структур данных: иногда они используются в качестве кортежей, иногда в виде списков:

  • Кортеж:

    • Фиксированная длина
    • Доступ к элементам напрямую по индексу

    Пример: возвращение нескольких значений из функции или метода.

  • Список:

    • Динамическая длина
    • Итерировать по всем элементам

сходства

Учитывая, что объект отображает имена в значения, а массив отображает натуральные числа в значения, очевидно, что записи и кортежи похожи. Их структура и диапазон одинаковы, отличается только их (функциональный) домен. То же самое касается карт и списков.

Смешение доменов «определение программы» и «данные приложения»

Объекты выполняют обязанности в двух областях: они иногда определяют программу, иногда содержат данные приложения.

  • Область определения программы: Объект представляет собой структуру данных, содержащую логику программы. В основном они используются в качестве записей в этом домене.
  • Область данных приложения. Объект представляет собой структуру данных, содержащую данные приложения. Объекты здесь используются в качестве записей и карт. Данные JSON являются частью этого домена.

Перекрытие двух доменов становится негативным, когда вы вызываете методы для объекта как карты, которые могут иметь произвольные ключи. Например, следующая функция заключается в том, как наивно реализовать проверку на наличие ключа:

    function hasKey(obj, key) {
        return obj.hasOwnProperty(key);
    }

Нормальное использование:

    > hasKey({foo: 123}, "foo")
    true

Однако эта функция перестает работать должным образом, если в obj используется ключ hasOwnProperty:

    > hasKey({hasOwnProperty: 123}, "foo")
    TypeError: Property 'hasOwnProperty' of object #<Object> is not a function

Исправление заключается в следующем (есть другие вещи, на которые следует обратить внимание, о которых будет рассказано в следующем сообщении в блоге):

    function hasKey(obj, key) {
        return Object.prototype.hasOwnProperty.call(obj, key);
    }

То есть вы обращаетесь к методу напрямую и не используете алгоритм поиска свойства, чтобы найти его.

Смешивание доменов с оператором []

Оператор [] был установлен в основном языке программирования как конструкция данных приложения. Только JavaScript смешивает домены: он используется для данных приложения в массивах и в объектах как карты. Но он также используется в качестве метапрограммирующего средства для доступа к свойству через вычисленное имя. Первый вариант использования настолько част, что имеет смысл позволить пользовательским типам коллекций переопределять оператор []. Чтобы избежать конфликта с последним вариантом использования (который встречается не часто), необходимо ввести методы, которые выполняют эту задачу. Например, Object.getProperty (имя) и Object.setProperty (имя, значение). В предложении ECMAScript.next «
Преобразование объектной модели: разделение [] и доступ к свойству » показано, как сделать это чисто.

Связанное чтение

Следующие письма в списке рассылки es-обсудили этот пост:

  1. « Разделение [] и доступ к свойствам для коллекций » (автор Аллен Уирфс-Брок) указывает на определение программы двух областей и данные приложения.
  2. « Выбор спецификации, разрушающий массив » (Дэвид Херман) упоминает запись против карты и кортеж против списка.

 

С http://www.2ality.com/2012/01/roles-objects-arrays.html