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

Введение

Глядя на 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. Помните, что для примитивных типов данных не требуется глубокое равенство!

Спасибо за прочтение!

Пожалуйста, хлопайте и следуйте за мной, если вы найдете этот урок полезным и интересным.