Они очень похожи, но есть небольшая разница. Следуйте этому руководству, чтобы понять это.
Введение
Глядя на Stack Overflow, мы можем обнаружить, что многих программистов смущает разница между equal
и eql
. Тем более, что eql
выглядит просто как сокращение от equal
. Более того, в некоторых случаях оба утверждения работают одинаково!
Прочитав этот урок, вы поймете тонкую разницу.
Простой тест
Давайте начнем с очень простого теста, используя mocha
и chai
:
'use strict'; const { expect } = require('chai'); describe('expect', () => { it('it should equal', () => { const value1 = 1; const value2 = 1; expect(value1).to.equal(value2); }); });
Очевидно, что 1
равно 1
, поэтому тест пройден. Числа — это примитивные типы данных в JavaScript, поэтому, если мы на самом деле использовали ==
(оператор равенства), ===
(оператор строгого равенства) или eql
, результат будет таким же:
describe('expect', () => { it('it should equal', () => { const value1 = 1; const value2 = 1; const result = value1 == value2; const strictResult = value1 === value2; expect(value1).to.equal(value2); expect(value1).to.eql(value2); expect(result).to.equal(true); expect(strictResult).to.equal(true); }); });
В данном конкретном случае не имеет значения, какой оператор мы используем. Тест будет пройден, и разницы нет.
Сравнение объектов
Когда мы хотим сравнить два объекта в JavaScript, мы должны быть более осторожными. Простое и строгое равенство приведут к результату false
:
const obj1 = { foo: 'bar' }; const obj2 = { foo: 'bar' }; const result = obj1 == obj2; // false const strictResult = obj1 === obj2; // false
Есть способы сравнить два объекта в JavaScript, но давайте сосредоточимся на chai
библиотеке и модульном тестировании.
Когда мы смотрим chai documentation, мы можем обнаружить, что разница между equal
заключается в следующем:
Утверждает, что цель строго (
===
) равна заданномуval
.
В то время как eql
:
Утверждает, что цель глубоко равна данному
obj
.
Отметим четыре ключевых слова: строго, глубоко, val и obj.
Таким образом, простое правило таково: когда мы хотим сравнить объекты, используйте eql
. В противном случае используйте equal
для сравнения значений.
Пример:
it('should equal', () => { expect({ a: 1 }).to.equal({ a: 1 }); // This fails as... const obj1 = { foo: 'bar' }; const obj2 = { foo: 'bar' }; const result = obj1 === obj2; // ...two objects are not strictly equal. expect(result).to.equal(true); // Thus result is false. });
Этот тест не пройден, так как мы использовали equal
, который строго сравнивает два значения. Это эквивалентно оператору ===
, который также дает false
.
Единственный способ, которым он может работать с объектом, — это когда мы сравниваем тот же объект с самим собой (что немного бессмысленно):
it('pointless comparison', () => { const object1 = { foo: 'bar' }; const object2 = object1; expect(object1).to.equal(object2); });
В этом случае мы проверяем, равен ли один объект object1
самому себе, поскольку мы присвоили object2
ссылку на object1
.
Мы могли бы даже переписать это как:
const object = { foo: 'bar' }; const result = object === object; // Even strict equal is true!
Глубокий равный
Мы должны признать, что соглашение об именах, используемое в chai
, не самое лучшее, поскольку eql
проверяет, полностью равны ли два объекта. Таким образом, лучшее имя, такое как deeplyEqual
, будет менее запутанным, и на самом деле оно есть!
Вместо использования eql
мы можем использовать: deep.equal
— это одно и то же:
it('should eql', () => { expect({ b: 2 }).to.eql({ b: 2 }); // Two objects are deeply equal. Test will pass. }); it('should deeply equal', () => { expect({ c: 3 }).to.deep.equal({ c: 3 }); // Test will pass });
Глубокое равенство означает, что два объекта имеют одинаковые свойства с одинаковыми значениями.
Краткое содержание
Ключевое отличие заключается в различном использовании. Используйте equal
для строгого сравнения значений, а если вы хотите сравнить объекты, используйте eql
, что эквивалентно глубокому равенству.
Название eql
вводит в заблуждение и сбивает с толку. Вместо этого вы всегда можете использовать: deep.equal
. Помните, что для примитивных типов данных не требуется глубокое равенство!
Спасибо за прочтение!
Пожалуйста, хлопайте и следуйте за мной, если вы найдете этот урок полезным и интересным.