Меню

Поверхностное сравнение объектов js



Как я могу сделать поверхностное сравнение свойств двух объектов с Javascript или lodash?

Есть ли способ, которым я могу сделать поверхностное сравнение, которое не будет опускаться и сравнивать содержимое объектов внутри объектов в Javascript или lodash? Обратите внимание, что я проверял lodash, но, похоже, он выполняет глубокое сравнение, которое я не хочу делать.

Есть ли способ, например, для сравнения a а также b ?

7 ответов

Так как это мелко, areEqualShallow(>, >) ложно

Это включает в себя любые свойства из прототипа.

Это использует === сравнение. Я полагаю, это то, что вы хотите. NaN === NaN это один случай, который может привести к неожиданным результатам. Если === это не то, что вы хотите, замените сравнение, которое вы хотите.

РЕДАКТИРОВАТЬ: если одинаковые ключи находятся в каждом объекте, то

Простой подход ES6:

Здесь я добавил, что проверка равенства количества ключей объекта для следующего сравнения должна завершиться неудачей (важный случай, который обычно не учитывается):

Имея в виду, что это только для мелкой и только для строк и чисел

Я рекомендую скопировать его в ваш собственный проект, если вам нужно его использовать, поскольку в их README четко указано, что они могут удалить или изменить этот и любой другой код в библиотеке без предупреждения.

Решение Пола Дрейпера можно оптимизировать, убрав сравнение во втором проходе.

Сделать «поверхностное» сравнение, где наследуемые свойства должны игнорироваться и NaN должен равняться NaN , следующее должно сделать работу. Он проверяет, что каждый объект имеет одинаковые собственные свойства и что значения === или оба NaN :

Используя последние функции, такие как Object.keys, чтобы получить собственные свойства, затем

Благодаря новым функциям, функция checkProperties может быть несколько упрощена:

Если вам действительно нужно проверить неопределенные значения, тогда это расширение должно удовлетворить @AndrewRasmussen:

В большинстве случаев вам не нужны все проверки, и вам нужно только проверить, содержит ли b все, что содержит a. Тогда а-центрическая проверка была бы действительно краткой:

Источник

Как я могу сделать поверхностное сравнение свойств двух объектов с Javascript или lodash?

Есть ли способ, которым я могу сделать поверхностное сравнение, которое не будет опускаться и сравнивать содержимое объектов внутри объектов в Javascript или lodash? Обратите внимание, что я проверял lodash, но, похоже, он выполняет глубокое сравнение, которое я не хочу делать.

Можно ли, например, сравнить a и b ?

7 ответов

Так как это мелко, areEqualShallow(>, >) ложно.

Это включает в себя любые свойства из прототипа.

Это использует === сравнение. Я полагаю, это то, что вы хотите. NaN === NaN — это один случай, который может привести к неожиданным результатам. Если === не то, что вам нужно, замените его на желаемое сравнение.

РЕДАКТИРОВАТЬ: если одинаковые ключи находятся в каждом объекте, то

Решение Пола Дрейпера можно оптимизировать, убрав сравнение во втором проходе.

Имея в виду, что это только для мелкой и только для строк и чисел

Чтобы выполнить «поверхностное» сравнение, в котором унаследованные свойства должны игнорироваться, а NaN должно равняться NaN , необходимо выполнить следующее. Он проверяет, что каждый объект имеет одинаковые собственные свойства и что значения === или оба NaN :

Используя последние функции, такие как Object.keys , чтобы получить собственные свойства, затем

Благодаря новым функциям функцию checkProperties можно несколько упростить:

Простой подход ES6:

Здесь я добавил, что проверка равенства количества ключей объекта для следующего сравнения должна провалиться (важный случай, который обычно не учитывается):

Обновление 2019 года . Согласно комментарию Эндрю Расмуссена, мы также должны принять во внимание случай undefined . Проблема с предыдущим подходом состоит в том, что следующее сравнение возвращает true :

Итак, необходима проверка существования явных ключей. И это можно сделать с помощью hasOwnProperty :

Я рекомендую скопировать его в ваш собственный проект, если вам нужно его использовать, поскольку их README четко заявляет, что они могут удалить или изменить этот и любой другой код в библиотеке без предупреждения.

Источник

Разбираемся с объектами в JavaScript

В этом материале автор — фронтенд-разработчик — сделал обзор основных способов создания, изменения и сравнения объектов JavaScript.

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

Читайте также:  Сравнение именованных чисел сначала выполняется с опорой

Лишь спустя некоторое время я начал понимать, что тема гораздо сложнее, чем я полагал. И тогда я стал изучать информацию из разных источников. Некоторые из них давали хорошее представление о предмете, но увидеть всю картину целиком я смог не сразу.

В этом посте я попытался охватить все аспекты работы с объектами в JS, не вдаваясь слишком глубоко в отдельные подробности, но и не упуская важные детали, которые помогут вам понять предмет и почувствовать себя увереннее во время его дальнейшего изучения.

Итак, давайте начнем с основ.

Объект

Объект в JavaScript — это просто набор свойств, каждое из которые представляет собой пару ключ-значение. Обратиться к ключам можно с помощью точечного (obj.a) или скобочного обозначения (obj[‘a’]).

Помните, что скобки следует использовать, если ключ:

  • не является допустимым JavaScript-идентификатором (в нем есть пробел, тире, начинается с цифры. )
  • является переменной.

Одно из свойств, которое объекты в JS получают при создании, называется Prototype, и это очень важное понятие.

Прототип

У каждого объекта в JavaScript есть внутреннее свойство под названием Prototype. В большинстве браузеров вы можете обратиться к нему по обозначению __proto__.

Prototype — это способ обеспечить наследование свойств в JavaScript. Так можно делится функциональностью без дублирования кода в памяти. Способ работает за счет создания связи между двумя объектами.

Проще говоря, Prototype создает указатель с одного объекта на другой.

Каждый раз, когда JS ищет свойство в объекте и не находит его непосредственно у самого объекта, он проверяет наличие свойства в объекте-прототипе. Если свойства нет и в нем, то JS продолжит поиск в прототипе связанного объекта. Так будет продолжаться до тех пор, пока JS не найдет подходящее свойство или не достигнет конца цепочки.

Давайте рассмотрим пример:

cons — это конструктор (просто функция, которую можно вызывать с помощью оператора new).

На пятой строке мы создаем новый объект — новую копию cons. Сразу после создания obj также получает свойство прототипа.

А теперь мы добавляем свойства (‘b’, ‘c’) прототипу объекта cons.
Рассмотрим obj:

obj.a // 1 — здесь все по-старому, obj.a по-прежнему равен 1.
obj.c — у obj нет свойства c! Однако, как ранее упоминалось, JS теперь поищет его в прототипе obj и вернет значение 4.

А теперь давайте подумаем, каково значение obj.b и каким оно станет, когда мы удалим obj.b?

Obj.b равен 2. Мы назначили свойство b, но мы сделали это для прототипа cons, поэтому когда мы проверяем obj.b, то по-прежнему получаем 2. Однако сразу после удаления obj.b JS уже не сможет найти b у obj, и потому продолжит поиск в прототипе и вернет значение 3.

Далее я хочу коротко рассказать о различных способах создания объекта и немного больше о прототипах.

Создание объекта

Литерал объекта: let obj = ;
Мы создали объект со следующей цепочкой прототипов: obj —> Object.prototype —> null
Как вы можете догадаться, object.prototype — это прототип объекта, а также конец цепочки прототипов.

Object.create(): var newObj = Object.create(obj);
У newObj будет следующая цепочка прототипов: newObj —> obj —> Object.prototype —> null

Конструктор. Как и в приведенном выше примере, конструктор — это просто JS-функция, позволяющая нам воспользоваться оператором new для создания новых ее экземпляров.

Square — экземпляр конструктора rectangle, и поэтому мы можем вызвать square.getArea() //4, square.width, а также все функции, унаследованные от object.prototype.

Какой из способов лучше? Если вы планируете создать несколько экземпляров, можно воспользоваться ES6 или конструктором. Если же вы планируете создать объект один раз, то лучше задать литерал, поскольку это самый простой способ.

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

Сравнение и изменение объектов

В JavaScript объекты относятся к ссылочному типу

Когда мы создаем объект let obj = ;, переменная obj получает адрес в памяти объекта, но не его значение! Крайне важно понимать эту разницу, поскольку в противном случае могут возникнуть ошибки. Когда мы создаем другой объект let newObj = obj, мы фактически создаем указатель на некую область памяти obj, а не абсолютно новый объект.

Читайте также:  Сравнение процессор для сервера

Это значит, что выполняя newObj.a = 2, мы фактически изменяем obj таким образом, что obj.a становится равен 2!

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

Из сказанного выше также вытекает, что два объекта никогда не могут быть равными, даже если они обладают одинаковыми свойствами. Это связано с тем, что JS по факту сравнивает расположение в памяти объектов, а два объекта никогда не находятся в одной ячейке памяти.

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

Рассмотрим несколько возможностей.

Допустим, ясно, что по-хорошему нам не следует изменять объекты, поэтому мы хотим создать копию соответствующего объекта и изменить ее свойства. На помощь приходит Object.assign().

Если мы захотим изменить значение свойства a объекта obj, можно воспользоваться object.assign для создания копии obj и ее изменения.

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

Пожалуйста, обратите внимание, что этот способ не сработает для глубокого копирования. Говоря о глубоком копировании, мы имеем в виду, что нужно скопировать объект с одним или несколькими свойствами.

Object.assign() копирует свойства объекта, поэтому если значение свойства — это указатель на объект, то копируется только указатель.

Для глубокого копирования необходима рекурсивная операция. Здесь можно написать функцию или просто воспользоваться методом _.cloneDeep из библиотеки Lodash.

Есть один классный прием работы с объектами — строчное преобразование. В следующем примере мы преобразовываем оба объекта в строки и сравниваем их:

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

Другое хорошее решение — воспользоваться методом _.isEqual из Lodash, выполняющим глубокое сравнение объектов.

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

Постарайтесь подумать над решением самостоятельно перед тем, как прочитать ответ.

Как узнать длину объекта?

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

  • for in. Этот метод охватывает все счетные свойства объекта и цепочки его прототипов. Мы познакомились с прототипом (и, надеюсь, усвоили материал), поэтому должно быть ясно, что применение for in не всегда будет верным для получения свойств объекта.
  • Object.keys. Этот способ возвращает массив с ключами всех собственных (принадлежащих указанному объекту) счетных свойств. Такой подход лучше, поскольку мы работаем только над свойствами объекта, не обращаясь к свойствам prototype. Бывают, однако, ситуации, когда вы присвоили атрибуту enumerable некоторого свойства значение false, и object.keys в итоге пропускает его, а вы получаете некорректный результат. Такое происходит редко, но в подобных случаях очень кстати придется getOwnPropertyNames.
  • getOwnPropertyNames возвращает массив, содержащий все собственные ключи объекта (как счетные, так и несчетные).

Также следует упомянуть:

  • Object.values перебирает собственные счетные свойства и возвращает массив с соответствующими значениями.
  • Object.entries перебирает собственные счетные свойства и возвращает массив с ключами и их значениями.

Думаю, вы заметили, что большинство из перечисленных выше методов возвращают массив. Это возможность воспользоваться всеми преимуществами методов JavaScript для работы с массивами.

Один из таких методов — array.length. В итоге мы можем просто написать

Как проверить, пуст ли объект?

В заключение

Надеюсь, теперь вы чувствуете себя увереннее в создании объектов и работе с ними. Давайте подытожим:

  • Помните, что объекты относятся к ссылочному типу, а значит, с ними рекомендуется работать без изменения оригинальных объектов.
  • Подружитесь со свойством prototype и цепочкой прототипов.
  • Познакомьтесь с инструментами-помощниками в работе с объектами. Помните, что можно превращать объекты в строки, получать массив с их ключами или просто перебирать их свойства с помощью набора методов, с которым мы познакомились.
Читайте также:  Сравнение электрических зубных щеток oral b таблица

Желаю удачи в изучении объектов JavaScript.

Источник

Сравнить два объекта в Javascript

У меня есть AJAX запрос. Выполняется каждые пять секунд.

Как мне передать значения из объекта myPlacemark в объект b и сравнить их (одинаковы они или нет)?

4 ответа 4

Для сравнения двух обьектов в Javascript не существует специальных операторов или простых способов.

Но вы можете воспользоваться замечательной библиотекой underscore вам нужна функция _.isEqual

Существует поверье что сравнивать объекты — это моветон (в JS точно, где почти всё — объект, про другие ЯП не знаю, но вряд ли это хороший тон).
Просто из-за того, что это бессмысленно.
Обычно сравнивают несколько полей, если это объекты запроса и на этом хватит.
Если очень хочется, то можно пройтись по объектам for..in и сравнить ключи и значения. Правда нет гарантий — свойства могут быть с флагом DontEnum .
Но обычные объекты (не встроенные) и достаточно простые (без назначений скрытого флага через Object.defineProperty ) можно проверить.
Флаг (не DontEnum :)) в руки!

Написал для себя небольшую функцию для сравнения объектов. Используется у меня для верного реагирование на изменение параметров в файле настроек. Присылает в качестве результата отличающиеся параметры из newObject. Если в newObject свойство отсутствует, а в oldObject есть, то это тоже будет отображено.

Лучше сделать, чтобы сервер присылал только изменения, а не полные объекты.

А для сравнений — рекурсивная функция, которая сравнивает на равенство, если непримитивные элементы не равны (по ссылке), то вызывает себя рекурсивно. Если примитивные объекты не равны, либо свойства нет в объекте, то всё. Не забыть пройти по свойствам второго объекта и проверить их наличие в первом.

Если есть уверенность, что при одинаковых значениях сервер вернёт одинаковый json, можно где-то сохранить ответ сервера в виде строки и сравнивать их.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками ajax javascript объекты или задайте свой вопрос.

Связанные

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.3.29.38936

Источник

Как я могу сделать поверхностное сравнение свойств двух объектов с Javascript или lodash?

Есть ли способ, которым я могу сделать поверхностное сравнение, которое не будет опускаться и сравнивать содержимое объектов внутри объектов в Javascript или lodash? Обратите внимание, что я проверял lodash, но, похоже, он выполняет глубокое сравнение, которое я не хочу делать.

Есть ли способ, например, для сравнения a а также b ?

7 ответов

Так как это мелко, areEqualShallow(>, >) ложно

Это включает в себя любые свойства из прототипа.

Это использует === сравнение. Я полагаю, это то, что вы хотите. NaN === NaN это один случай, который может привести к неожиданным результатам. Если === это не то, что вы хотите, замените сравнение, которое вы хотите.

РЕДАКТИРОВАТЬ: если одинаковые ключи находятся в каждом объекте, то

Простой подход ES6:

Здесь я добавил, что проверка равенства количества ключей объекта для следующего сравнения должна завершиться неудачей (важный случай, который обычно не учитывается):

Имея в виду, что это только для мелкой и только для строк и чисел

Я рекомендую скопировать его в ваш собственный проект, если вам нужно его использовать, поскольку в их README четко указано, что они могут удалить или изменить этот и любой другой код в библиотеке без предупреждения.

Решение Пола Дрейпера можно оптимизировать, убрав сравнение во втором проходе.

Сделать «поверхностное» сравнение, где наследуемые свойства должны игнорироваться и NaN должен равняться NaN , следующее должно сделать работу. Он проверяет, что каждый объект имеет одинаковые собственные свойства и что значения === или оба NaN :

Используя последние функции, такие как Object.keys, чтобы получить собственные свойства, затем

Благодаря новым функциям, функция checkProperties может быть несколько упрощена:

Если вам действительно нужно проверить неопределенные значения, тогда это расширение должно удовлетворить @AndrewRasmussen:

В большинстве случаев вам не нужны все проверки, и вам нужно только проверить, содержит ли b все, что содержит a. Тогда а-центрическая проверка была бы действительно краткой:

Источник