Доступ к полю по переменной в массиве объектов JavaScript

Я столкнулся с проблемой при попытке доступа к отдельным полям объектов, хранящихся в массиве.

У меня есть массив неоднородных объектов, назовем его тайник.

var cache = new Array();

Функция ставить позволяет добавлять элементы в массив.

function put(item, value) {
  cache[item] = value;
}

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

var item_abc = { item_a: 'some value', item_b: 'another value' };

put('ITEM_ABC',item_abc);

Проблемная функция называется Обновить, которая обновляет поле для пункт в массиве с новым значение.

function update(item, field, value) {
  cache[item][field] = value;
}

Вот неприятный код:

update('ITEM_ABC','item_a','a new value');

В браузере это вроде работает нормально, но в среде Node.js "--use_strict" возникают проблемы. Я предполагаю, что это связано с приоритетом и способом, которым многомерные массивы оцениваются по сравнению с полями объекта.

Как мне ссылаться на поле объекта, не зная имени поля во время выполнения, когда сам объект существует в массиве?

Чтение из рассматриваемого поля всегда возвращает неопределенный.

function check(item, field) {
  console.info(cache[item][field]);
  if (typeof cache[item][field] !== 'undefined')
    console.info('field exists');
  else
    console.info('field undefined');
}

Бег:

check('ITEM_ABC','item_a');

Выходы:

undefined
'field undefined'

Можете ли вы сообщить нам, с какой ошибкой вы сталкиваетесь при использовании use strict?

Joe Lissner 04.06.2018 21:35

Я не вижу в этом вопросе JSON. JSON - это формат сериализации данных. Похоже, вы говорите об объектах JavaScript.

Jordan Running 04.06.2018 21:42

Нет ошибка, но typeof cache[item][field] всегда undefined

lagbot 04.06.2018 21:43

Начните с var cache = {}; (в JavaScript нет ассоциативных массивов).

Chris G 04.06.2018 21:43

Если вы используете строгий режим, у вас не может быть переменной с именем package.

Ammar 04.06.2018 21:47

У меня нормально работает drive.google.com/open?id=1w5k29WXGQNIdxvJ6CL4-2FnETs78YVpG

Ammar 04.06.2018 21:55

Я внес некоторые изменения, чтобы учесть эти комментарии. Основная проблема, похоже, заключается в том, чтобы проверить, действительно ли typeof cache[item][field] !== 'undefined'

lagbot 04.06.2018 22:13
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
7
196
1

Ответы 1

Я рекомендую упрощенные функции get и put. Если вы хотите реализовать специализированный update, он должен использовать get и put.

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, field, value) =>
  put ( key
      , { ... get (key) || {}, [field]: value }
      )

put ('foo', { a: 1 })

console.info (get ('foo')) // { a: 1 }

update ('foo', 'a', 2)

console.info (get ('foo')) // { a: 2 }

Выше мы пишем функции максимально просто. Но, возможно, более гибким способом записи update будет что-то вроде Object.assign, где вы можете обновить объект, используя другой объект.

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )
      
put ('foo', { a: 1, b: 2 })

console.info (get ('foo')) // { a: 1, b: 2 }

update ('foo', { a: 2, c: 2 })

console.info (get ('foo')) // { a: 2, b: 2, c: 2 }

Если вы хотите поддерживать несколько кешей, вы можете заключить интерфейс get, put, update в другую функцию. Ниже мы демонстрируем возможность взаимодействия с двумя отдельными кешами, c1 и c2.

const makeCache = () =>
{ const cache =
    {}

  const get = (key) =>
    cache[key]

  const put = (key, value) =>
    cache[key] = value

  const update = (key, obj) =>
    put ( key
        , Object.assign (get (key) || {}, obj)
        )
        
  return { get, put, update }
}
 
const c1 = makeCache ()
const c2 = makeCache ()

c1.put ('foo', { a: 1 })
c2.put ('foo', { a: 2 })

console.info (c1.get ('foo')) // { a: 1 }
console.info (c2.get ('foo')) // { a: 2 }

c1.update ('foo', { z: 3 })

console.info (c1.get ('foo')) // { a: 1, z: 3 }
console.info (c2.get ('foo')) // { a: 2 }

Наконец, использование объекта {} для cache на самом деле не идеально, поскольку key всегда преобразуется в строку до того, как с ней может быть связано значение. Та же проблема возникает, когда мы используем массив [], как и в исходном коде. Посмотрите, что происходит, когда мы используем непримитивное значение в качестве ключа ...

const cache =
  {}

const get = (key) =>
  cache[key]

const put = (key, value) =>
  cache[key] = value

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )

const k1 = { foo: "bar" }
const k2 = { hello: "world" }

put (k1, 1)

console.info (get (k1)) // 1
console.info (get (k2)) // 1 ???

Выше, несмотря на то, что мы никогда не использовали put как значение для k2, мы все же можем get как значение, потому что строковое представление k1 и k2 одинаково - каждое из них преобразуется в [object Object] перед сохранением значения. Ниже мы избегаем этой проблемы, используя Map.

const cache =
  new Map

const get = (key) =>
  cache .get (key)

const put = (key, value) =>
  cache .set (key, value)

const update = (key, obj) =>
  put ( key
      , Object.assign (get (key) || {}, obj)
      )

const k1 = { foo: "bar" }
const k2 = { hello: "world" }

put (k1, 1)

console.info (get (k1)) // 1
console.info (get (k2)) // undefined

put (k2, 2)
   
console.info (get (k1)) // 1
console.info (get (k2)) // 2

Другие вопросы по теме