Разница в производительности JavaScript между двойными равными (==) и тройными равными (===) - PullRequest
38 голосов
/ 08 ноября 2011

В JavaScript, есть ли разница в производительности между использованием двойного равенства (==) и использованием тройного равенства (===)?

Пример: if (foo == bar) против if (foo === bar)

Ответы [ 6 ]

40 голосов
/ 08 ноября 2011
  • Если сравниваемые типы одинаковы, они идентичны .То есть они используют точно такой же алгоритм .

  • Если типы отличаются , то производительностьне имеет значения.Либо вам нужно принуждение к типу, либо нет.Если вам это не нужно, не используйте ==, потому что полученный результат может быть неожиданным.

27 голосов
/ 08 ноября 2011

Строгое сравнение (===) всегда будет немного быстрее, но разница обычно незначительна .

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

14 голосов
/ 08 ноября 2011

Редактировать: для справки вот по спецификации объяснение д-ра Акселя Раушмайера http://www.2ality.com/2011/06/javascript-equality.html Действительно здорово написать.

=== (Строгое равенство): учитываются только равные значения одного типа.

  1. undefined === undefined, null === null,
  2. NaN === ничего, включая себя,
  3. Примитив [Number | String | Boolean] === значение примитива равно,
  4. к себе (+0 === -0)
  5. Два объекта [Массив | Объект | Функция] === Только сам (та же самая сущность)

== (Меньшее равенство)

  1. Если оба значения имеют одинаковый тип: сравните с ===.
  2. undefined == null
  3. число и строка: строка => число и сравнение
  4. булево и не булево => не булево число и сравнить
  5. строка или число => объект: преобразовать объект в примитив и сравнение.

Во всех современных средах Javascript они реализованы совершенно по-разному. Проще говоря, == проверяет сходство путем преобразования заданных переменных в примитивы (строка, число, логическое значение). === проверяет на строгость одинаковости, что означает точно такой же объект или примитивное значение без преобразования.

Если вы делаете objOne == objTwo что на самом деле происходит [[EQUALS]].call(objOne.valueOf(), objTwo.valueOf())

Разрешение valueOf может в некоторой степени влиять на функции, представленные в JS, и на внутренние компоненты движка. Достаточно сказать, что сравнение всегда будет заканчиваться двумя значениями, приведенными к примитиву, иначе будет выдано сообщение об ошибке.

Редактировать: EQUALS сначала пытается STRICT_EQUALS, что прерывает остальную часть процесса.

Интересным здесь является то, что valueOf (и его партнер toString) могут быть переопределены. Запустите этот кусок кода в Chrome (я думаю, что любой webkit, не уверен, что JSC и V8 разделяют этот лакомый кусочек). Это взорвет ваш разум:

var actions = [];
var overload = {
  valueOf: function(){
    var caller = arguments.callee.caller;
    actions.push({
      operation: caller.name,
      left: caller.arguments[0] === this ? "unknown" : this,
      right: caller.arguments[0]
    });
    return Object.prototype.toString.call(this);
  }
};
overload.toString = overload.valueOf;
overload == 10;
overload === 10;
overload * 10;
10 / overload;
overload in window;
-overload;
+overload;
overload < 5;
overload > 5;
[][overload];
overload == overload;
console.log(actions);

Выход:

[ { operation: 'EQUALS',
    left: overload,
    right: 10 },
  { operation: 'MUL',
    left: overload,
    right: 10 },
  { operation: 'DIV',
    left: 'unknown',
    right: overload },
  { operation: 'IN',
    left: overload,
    right: DOMWindow },
  { operation: 'UNARY_MINUS',
    left: overload,
    right: undefined },
  { operation: 'TO_NUMBER',
    left: overload,
    right: undefined },
  { operation: 'COMPARE',
    left: overload,
    right: 5 },
  { operation: 'COMPARE',
    left: 'unknown',
    right: overload },
  { operation: 'ToString',
    left: 'unknown',
    right: overload } ]

Суть различия между == и === иллюстрируется тем, что === не отображается в этом списке. Он полностью пропускает путешествие в JavascriptLand. Это приключение стоит дорого при сравнении производительности.

Однако вам необходимо учитывать оптимизацию движка. Для большинства объектов движок сможет вырезать большинство шагов и остаться в NativeLand и получить почти такую ​​же производительность. Но это не гарантия, и если что-то мешает движку использовать оптимизацию, некоторую фантазию в вашем коде или переопределение встроенных функций или множество проблем, то вы сразу же увидите результат в производительности. === заставляет его.

=== - это почти единственная неизменная вещь в Javascript.

3 голосов
/ 08 ноября 2011

Из-за производительности, я думаю, === имеет лучшую производительность, потому что === строже, чем ==,

, например, попробуйте следующее в консоли Chrome.

> 1 == '1'
  true
> 1 === '1'
  false

== должен проверить больше вещей, чем ===

1 голос
/ 08 ноября 2011

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

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

РЕДАКТИРОВАТЬ: на самом деле, кажется, зависит от того, что вы сравниваете, и от реализации браузера.Другими словами, не беспокойтесь об этом.

0 голосов
/ 08 февраля 2019

Зависит от сравниваемых предметов. Поскольку "===" более строго, чем "==", он должен возвращать false быстрее, чем "==". Однако, если эти два элемента строго равны, «===» должно занять больше времени, чем «==», поскольку необходимо проверить больше свойств на равенство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...