Питання Який дорівнює оператору (== vs ===) слід використовувати для порівняння JavaScript?


Я використовую JSLint щоб пройти через JavaScript, і це повертає багато пропозицій замінити == (дві знаки рівного) з === (три рівні ознаки), коли ви робите такі речі, як порівняння idSele_UNVEHtype.value.length == 0 всередині ан if заява

Чи є перевага продуктивності для заміни == з ===?

Будь-яке поліпшення продуктивності буде прийнято, оскільки існують численні оператори порівняння.

Якщо жодного типу перетворення не відбувається, чи буде збільшення продуктивності ==?


5674
2017-12-11 14:19


походження


Для кого це може зацікавити той самий предмет === vs ==, але в PHP, можна прочитати тут: stackoverflow.com/questions/2401478/why-is-faster-than-in-php/... - Marco Demaio
Тільки у випадку, якщо хтось цікавить у 2012 році: === є шлях швидше за ==. jsperf.com/comparison-of-comparisons - Ry-♦
@minitech має бути таким, як це не робить перетворення типу - Umur Kontacı
@ minitech, я сумніваюся, що хтось збирається зробити їх застосування помітно швидше, використовуючи === над ==. По суті, тест не відрізняється як від сучасних браузерів. Особисто я звичайно користуюсь == скрізь, якщо мені не потрібна сувора рівність. - this.lau_
@johndodo: Передчасна оптимізація - це лише річ, оскільки оптимізований код може бути менш ідеальним з точки зору ремонтопригодності та зручності читання, але якщо функції перетворення типу == не потрібні, використання === Натомість це хороша практика, а не передчасна оптимізація. Тут нічого немає === що погіршує коректність чи зручність читання. - Robert Harvey♦


Відповіді:


Особистість (===) оператор поводиться тотожно рівності (==) за винятком того, що перетворення типу не відбувається, а типи повинні бути однаковими, щоб вважатися рівними.

Довідка: Підручник з Javascript: оператори порівняння

The == Оператор буде порівнювати для рівності після виконання будь-якого необхідного перетворення типу. The === оператор буде ні виконайте перетворення, отже, якщо два значення не однакового типу === просто повернеться false. Обидва вони однаково швидкі.

Цитувати Дуглас Крокфорд відмінно JavaScript: хороші частини,

JavaScript має два набори операторів рівності: === і !==, і їхні злі близнюки == і !=. Добрі діють так, як ви очікуєте. Якщо два операнда мають однаковий тип і мають однакове значення, то === випускає true і !== випускає false. Зло близнюки роблять правильну дію, коли операнди одного типу, але якщо вони різні типи, вони намагаються примусити ці цінності. правила, за якими вони роблять це, є складними і незабутніми. Ось деякі з цікавих випадків:

'' == '0'           // false
0 == ''             // true
0 == '0'            // true

false == 'false'    // false
false == '0'        // true

false == undefined  // false
false == null       // false
null == undefined   // true

' \t\r\n ' == 0     // true

Брак транзитивності викликає тривогу. Моя порада ніколи не використовувати злих близнюків. Замість цього завжди використовуйте === і !==. Всі порівняння показали тільки false з === оператор


Оновлення:

Хороший момент був піднятий @ Casebash в коментарях і в @ Філіп Лейберт  відповісти щодо типів довідок. Для еталонних типів == і === діяти послідовно один з одним (крім особливого випадку).

var a = [1,2,3];
var b = [1,2,3];

var c = { x: 1, y: 2 };
var d = { x: 1, y: 2 };

var e = "text";
var f = "te" + "xt";

a == b            // false
a === b           // false

c == d            // false
c === d           // false

e == f            // true
e === f           // true

Спеціальний випадок полягає в тому, що ви порівнюєте буквальне слово з об'єктом, який оцінює ту ж літературу, через її toString або valueOf метод Наприклад, розглянемо порівняння рядкового буктеля з строковим об'єктом, створеним String конструктор

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

Ось тут == Оператор перевіряє значення двох об'єктів та повертає їх true, але === бачимо, що вони не схожі і повертаються false. Який з них правильний? Це дійсно залежить від того, що ви намагаєтесь порівняти. Моя порада полягає в тому, щоб цілком обійти питання і просто не використовувати String конструктор для створення рядкових об'єктів.

Посилання
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


5728
2017-12-11 14:25



=== не швидше, якщо типи однакові. Якщо типи не однакові, === буде швидше, оскільки він не намагатиметься здійснити конверсію. - Bill the Lizard
=== ніколи не буде повільніше, ніж ==. Вони обидва проводять перевірку типу, тому === не робить нічого зайвого порівняно з ==, але перевірка типу може дозволити === вийти раніше, коли типи не однакові. - Bill the Lizard
Заміна всіх == /! = З === /! == збільшує розмір js-файлу, це займе більше часу для завантаження. :) - Marco Demaio
"... правила, за якими вони роблять це, є складними та незабутніми ..." Тепер такі заяви роблять вас настільки безпечними, коли програмують ... - Johan
Інколи система типу JavaScript робить мене захопленим кричати. - Yawar


Використовуючи ==оператор (Рівність)

true == 1; //true, because 'true' is converted to 1 and then compared
"2" == 2;  //true, because "2" is converted to 2 and then compared

Використовуючи ===оператор (Ідентичність)

true === 1; //false
"2" === 2;  //false

Це тому, що оператор рівності == чи є типом примусу, що означає, що інтерпретатор неявно намагається перетворити значення перед порівнянням.

З іншого боку, оператор ідентифікації === не робить примусу типу, і, таким чином, не перетворює значення при порівнянні.


990
2018-06-05 19:11



@ Програмне забезпечення Monkey: не для типів значень (number, boolean, ...) - Philippe Leybaert
type coercion vs type casting vs type convertion: stackoverflow.com/questions/8857763/... - Adrien Be
Оскільки ніхто не згадав Таблицю рівності Javascript, ось це: dorey.github.io/JavaScript-Equality -Table - blaze
У першому твердженні ви впевнені, що "true" перетворюється в 1, а не в 1, перетворене в істину? - Shadi Namrouti
Звідки беруться терміни "рівність" та "ідентичність"? Стандарт не використовує ці терміни. Це викликає == "абстрактна рівність" і це викликає === "сувора рівність". Отримано дзвінок == будь-яка "рівність" IMHO жахлива, оскільки вона не транзитивна, але чому ж кмітливість? Я приймаю більше питань з "ідентифікацією", хоча; Я думаю, що цей термін є досить оманливим, хоча це "працює". Але серйозно, хто створив термін "ідентичність"? Я шукаю стандарт і не можу знайти його. - Ray Toal


У відповідях тут я нічого про що не читав рівний засоби. Деякі скажуть це === засоби рівний і того ж типу, але це неправда. Це насправді означає, що обидва операнда посилаються на той самий об'єкт, або у випадку типи значень, мають однакове значення.

Отже, візьмемо наступний код:

var a = [1,2,3];
var b = [1,2,3];
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Тут теж саме:

var a = { x: 1, y: 2 };
var b = { x: 1, y: 2 };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Або навіть:

var a = { };
var b = { };
var c = a;

var ab_eq = (a === b); // false (even though a and b are the same type)
var ac_eq = (a === c); // true

Така поведінка не завжди очевидна. Існує більше історії, ніж рівність і бути того ж типу.

Правило:

Для типів вартості (чисел):
a === b повертає true, якщо a і b мають однакову цінність і мають однаковий тип

Для типів референції:
a === b повертає true, якщо a і b посилання на той самий об'єкт

Для рядків:
a === b повертає true, якщо a і b це обидва рядки і містять точно такі ж символи


Струни: особливий випадок ...

Струни - це не типи значень, але в Javascript вони поводяться як типи значень, тому вони будуть "рівними", коли символи в рядку однакові і коли вони мають однакову довжину (як пояснено в третьому правилі)

Тепер стає цікаво:

var a = "12" + "3";
var b = "123";

alert(a === b); // returns true, because strings behave like value types

Але як про це ?:

var a = new String("123");
var b = "123";

alert(a === b); // returns false !! (but they are equal and of the same type)

Я думав, що струни поводяться як цінні типи? Ну, це залежить від того, хто ви запитуєте ... У цьому випадку a та b не є однаковими. a є типу Object, поки b є типу string. Просто пам'ятайте, що створення рядкового об'єкта з використанням String конструктор створює щось типу Object що веде себе як рядок більшу частину часу.


546
2018-05-05 05:21



activa: Я б уточнив, що рядки настільки рівноправні, лише коли вони є літералами. новий рядок ("abc") === "abc" є помилковим (згідно з моїм дослідженням). - Lawrence Dol
new Number() == "0". Також у Firefox: (function(){}) == "function () {\n}" - Thomas Eding
Дякую, що пояснили чому new String("123") !== "123". Вони різні типи. Простий, але заплутаний. - styfle
String об'єкти ведуть себе як рядки, як це робить будь-який інший об'єкт. new String ніколи не слід використовувати, оскільки це не створює реальних рядків. Реальний рядок і може бути зроблений за допомогою строкових літералів або дзвінків String як функція без  new, наприклад: String(0); //"0", Real string, not an object - Esailija
Але у випадках, коли ви докладно, оператор "==" поводиться точно так само. - Yaron Levi


Цікаве живописне зображення порівняння рівності між == і ===.

Джерело: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

При використанні === для випробувань рівності JavaScript, все як є. Нічого не перетворюється перед оцінкою.

Equality evaluation of === in JS


var1 == var2

При використанні == для перевірки рівності JavaScript, деякі   фанки перетворення відбуваються.

Equality evaluation of == in JS

Мораль історії: 

Використовуйте === якщо ви повністю не зрозумієте це   конверсії, які відбуваються з ==.


522
2017-11-28 18:18



@mfeineis ви маєте на увазі === або! == замість == або! =. Не хочу плутати нові кодеки;) - katalin_2003
@ katalin_2003 ой, ти правий === і! ==, d ** n описи, thx - mfeineis
@vsync: Вау, ті люди, які зловживають JQuery, також говорять про одне й те саме. Я ніколи не знав, що у вас так багато спільного ...
@ vsync: якщо ви насправді не хочуть, щоб типи були рівними, ви повинен використовувати три дорівнює! - SNag
Ця відповідь настільки корисна !!! - skiabox


Дозвольте мені додати цю пораду:

Якщо ви сумніваєтесь, прочитайте специфікація! 

ECMA-262 - це специфікація мови скриптів, якою JavaScript є діалект. Звичайно, на практиці важливіше те, як ведуть себе найважливіші браузери, ніж езотеричне визначення того, як щось повинно розглядатися. Але корисно зрозуміти, чому новий рядок ("a")! == "a".

Будь ласка, дайте мені пояснити, як прочитати специфікацію, щоб прояснити це питання. Я бачу, що в цій дуже старій темі ніхто не мав відповіді на дуже дивний ефект. Отже, якщо ви можете прочитати специфікацію, це допоможе вам у вашій професії величезно. Це придбане майстерність. Отже, давайте продовжимо.

Пошук PDF-файлу для === приводить мене до сторінки 56 специфікації: 11.9.4. Оператор строгого рівня (===), і після того, як вирушили через спеціальну основну інформацію, я вважаю:

11.9.6 Алгоритм строгого порівняння рівності
  Здійснюється порівняння x === y, де x та y - значення правда або помилковий. Таке порівняння виконується наступним чином:
  1. Якщо Type (x) відрізняється від типу (y), поверніться помилковий.
  2. Якщо Type (x) Undefined, поверніться правда.
  3. Якщо Type (x) є Null, поверніться правда.
  4. Якщо Type (x) не є номером, перейдіть до кроку 11.
  5. Якщо х є NaN, повернення помилковий.
  6. Якщо y є NaN, повернення помилковий.
  7. Якщо x - таке ж число, що і y, повертаємо правда.
  8. Якщо x є +0, а у - 0, поверніться правда.
  9. Якщо x -0 і y +0, поверніться правда.
  10. Повернення помилковий.
  11. Якщо Type (x) - String, то поверніться правда якщо x та y точно такі ж послідовності символів (однакова довжина і однакові символи у відповідних позиціях); інакше, повернення помилковий.
  12. Якщо Type (x) є логічним, поверніться правда якщо x та y обидва правда або обидва помилковий; інакше, повернення помилковий.
  13. Повернення правда якщо x та y відносяться до того ж об'єкту або якщо вони стосуються об'єктів, об'єднаних один з одним (див. 13.1.2). Інакше, поверніться помилковий.

Цікаво, це крок 11. Так, рядки розглядаються як типи значень. Але це не пояснює чому новий рядок ("a")! == "a". Чи є у нас браузер, який не відповідає ECMA-262?

Не так швидко!

Давайте перевіримо типи операндів. Спробуйте самі, загорнувши їх тип(). Я це знаходжу новий рядок ("a") є об'єктом, і використовується крок 1: return помилковий якщо типи різні.

Якщо вас цікавить чому новий рядок ("a") не повертає рядок, як щодо деяких вправ, читати специфікації? Весело проведіть!


Aidiakapi написав це в коментаря нижче:

З специфікації

11.2.2 Новий Оператор:

Якщо тип (конструктор) не є об'єктом, викиньте виняток TypeError.

Іншими словами, якщо String не буде тип Object, його не можна використовувати з новим оператором.

новий завжди повертає об'єкт, навіть для Строка конструктори теж. І, на жаль! Значення семантики для рядків (див. Крок 11) втрачається.

І це, нарешті, означає: новий рядок ("a")! == "a".


250
2018-05-12 12:58



Результат типу (x) має бути таким самим, як typeof? - Dfr


У PHP і JavaScript це строгий оператор рівності. А це означає, що він порівнює як тип, так і значення.


93
2017-12-25 11:17



@David: правильно Ось чому ця відповідь неточна (або навіть неправильна) - Philippe Leybaert
@David var a = {}, b = {};  a == b повертає помилково - nyuszika7h
Так: два інший об'єкти з тим самим типом і значенням порівнюють фальшивими, тобто ця відповідь є неправильною. Чому в ньому є 50 варіантів? - alexis
Я розумію, що це старе, але щоб з'ясувати, чому ця відповідь все ще "правильна", це тому, що в прикладі var a = {}, b = {}; Хоча обидва a і b це дійсно обидва об'єкти, але вони не є той же вартість, технічно кажучи. Вони є інший випадки Зверніть увагу, що порівняння екземплярів поводиться інакше, ніж порівняння примітивів. Що, ймовірно, додає цю плутанину. Ви побачите подібне поведінку порівняння, якщо ви використовуєте версію примірників примітивних типів даних. Напр new String('asdf') або new Number(5). Наприклад: new Number(5) == new Number(5) є помилковим, навіть якщо вони мають однакову цінність. - Norman Breau


Я тестував це в Firefox з Firebug використовуючи код, як це:

console.time("testEquality");
var n = 0;
while(true) {
    n++;
    if(n==100000) 
        break;
}
console.timeEnd("testEquality");

і

console.time("testTypeEquality");
var n = 0;
while(true) {
    n++;
    if(n===100000) 
        break;
}
console.timeEnd("testTypeEquality");

Мої результати (перевірені п'ять разів на кожну та усереднені):

==: 115.2
===: 114.4

Тому я б сказав, що мінімальна різниця (це понад 100000 повторень, запам'ятайте) є незначною. Продуктивність це не так причина зробити ===. Введіть безпеку (добре, настільки ж безпечно, наскільки ви збираєтеся входити в JavaScript), і якість коду.


88
2018-05-12 12:58



Більше, ніж безпеку типу, яку ви хочете логічної правильності - іноді ви хочете, щоб речі були правдиві коли == не погоджується - rpjohnst
Тепер, як порівнювати ці дані, коли існує фактична когерсія типу == оператор Пам'ятайте, що це коли підвищується продуктивність. - Hubert OG
Значна різниця при правильному тестуванні на вищезгадані причини швидше для перевірки нерівності типу. jsfiddle.net/4jhuxkb2 - Doug Morrow