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

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

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

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

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

5673
11 дек. заданий bcasp 11 дек. 2008-12-11 17:19 '08 о 17:19 2008-12-11 17:19
ответ 51 відповідь
  • 1
  • 2

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

Довідка: Javascript Tutorial: Оператори порівняння

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

Процитувати Douglas Crockford відмінно 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 в коментарях і в @Phillipe Laybaert щодо довідкових типів. Для довідкових типів == і === діють послідовно один з одним (за винятком спеціального випадку).

 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

5840
11 дек. відповідь дан Bill the Lizard 11 дек. 2008-12-11 17:25 '08 о 17:25 2008-12-11 17:25

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

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

Використовуючи оператор === (Identity)

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

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

З іншого боку, оператор Identity === не виконує тип примусу і, отже, не перетворює значення при порівнянні.

1016
11 дек. відповідь дан Andreas Grech 11 дек. 2008-12-11 17:33 '08 о 17:33 2008-12-11 17:33

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

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

 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 type 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 type 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 type 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 , яке більшу частину часу поводиться як рядок.

564
05 июня '09 в 22:11 2009-06-05 22:11 відповідь дан Philippe Leybaert 05 червня '09 о 22:11 2009-06-05 22:11

Цікаве графічне представлення порівняння рівності між == і === .

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


var1 === var2

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

2019

553
05 мая '14 в 8:21 2014-05-05 08:21 відповідь дан SNag 05 травня '14 в 8:21 2014-05-05 8:21

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

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

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

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

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

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

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

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

Перевірити типи операндів. Спробуйте самі, обернувши їх в typeof (). Я виявив, що новий String ( "a") є об'єктом, а використовується крок 1: return false, якщо типи відрізняються.

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


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

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

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

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

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

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

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

254
28 нояб. відповідь дан nalply 28 нояб. 2009-11-28 21:18 '09 о 21:18 2009-11-28 21:18

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

95
12 мая '10 в 15:58 2010-05-12 15:58 відповідь дан Shiki 12 травня '10 о 15:58 2010-05-12 15:58

Я тестував це в 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), і якість коду.

91
25 дек. відповідь дан Simon Scarfe 25 дек. 2008-12-25 14:17 '08 о 14:17 2008-12-25 14:17

В JavaScript це означає одне і те ж значення і тип.

наприклад,

 4 == "4" // will return true 

але

 4 === "4" // will return false 
88
12 мая '10 в 15:58 2010-05-12 15:58 відповідь дан Dimitar 12 травня '10 о 15:58 2010-05-12 15:58

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

Візьмемо 2 vars a і b.

Для "a == b" для оцінки істини a і b має бути одне значення.

У разі "a === b" a і b повинні бути однакове значення, а також того ж типу для нього для оцінки істини.

Візьмемо такий приклад

 var a = 1; var b = "1"; if (a == b) //evaluates to true as a and b are both 1 { alert("a == b"); } if (a === b) //evaluates to false as a is not the same type as b { alert("a === b"); } both var a = 1; var b = "1"; if (a == b) //evaluates to true as a and b are both 1 { alert("a == b"); } if (a === b) //evaluates to false as a is not the same type as b { alert("a === b"); } same type as b var a = 1; var b = "1"; if (a == b) //evaluates to true as a and b are both 1 { alert("a == b"); } if (a === b) //evaluates to false as a is not the same type as b { alert("a === b"); } 

На закінчення; використання оператора == може оцінюватися як справжнє в ситуаціях, коли ви цього не хочете, тому використання оператора === буде більш безпечним.

У сценарії використання 90% не має значення, який із них ви використовуєте, але корисно знати різницю, коли ви отримуєте якесь несподіване поведінку в один прекрасний день.

77
11 дек. відповідь дан Doctor Jones 11 дек. 2008-12-11 17:58 '08 о 17:58 2008-12-11 17:58

Він перевіряє, чи рівні однакові боку як за типом, так і за значенням.

приклад:

 '1' === 1 // will return "false" because 'string' is not a 'number' 

Загальний приклад:

 0 == '' // will be "true", but it very common to want this check to be "false" 

Інший поширений приклад:

 null == undefined // returns "true", but in most cases a distinction is necessary 
70
12 мая '10 в 15:58 2010-05-12 15:58 відповідь дан vsync 12 травня '10 о 15:58 2010-05-12 15:58

Чому == настільки непередбачуваний?

Що ви отримуєте, коли порівнюєте порожній рядок "" з номером 0 0 ?

<Код> Trueкод>

Так, це правильно відповідно до == порожній рядок, а числове нуль - одне і те ж час.

І це не закінчується, ось ще один:

  '0' == false//true Код> 

Речі стають дуже дивними з масивами.

  [1] == true//true [] == false//true [[]] == false//true [0] == false//true Код> 

Потім weerder з рядками

  [1,2,3] == '1,2,3'//true - ДЕЙСТВИТЕЛЬНО?! '\ r\n\t' == 0//true - Давай! Код> 

погіршується:

Коли одно не однаково?

  let A = ''//пустая строка пусть В = 0//нуль пусть C = '0'//нулевая строка A == B//true - ok... B == C//true - пока что так хорошо... A == C//** FALSE ** - Закручивание сюжета! Код> 

Дозвольте мені ще раз сказати:

  (A == B)(B == C)//true (A == C)//** FALSE ** Код> 

І це просто божевільний матеріал, який ви отримуєте з примітивами.

Це новий рівень божевілля, коли ви використовуєте == з об'єктами.

У цей момент вам, напевно, цікаво ...

Чому це відбувається?

Добре, тому що на відміну від "потрійного рівності" ( === ), який просто перевіряє, чи збігаються два значення.

== робить цілу купу інших речей.

Він має спеціальну обробку для функцій, спеціальну обробку для нулів, undefined, рядків, які ви називаєте.

Це стає досить безглуздим.

Насправді, якщо ви спробували написати функцію, яка робить те, що робить == , вона буде виглядати приблизно так:

  function isEqual (x, y) {//если `==` были функцией   if (typeof y === typeof x) return y === x;   // обрабатываем null и undefined то же самое   var xIsNothing = (y === undefined) || (y === null);   var yIsNothing = (x === undefined) || (x === null);  если (xIsNothing || yIsNothing) возвращается (xIsNothing  yIsNothing);  if (typeof y === "function" || typeof x === "function" ) {   // если любое значение является строкой   // преобразовать функцию в строку и сравнить   if (typeof x === "string" ) {   return x === y.toString();   } else if (typeof y === "string" ) {   return x.toString() === y;   }   return false;   }  if (typeof x === "object" ) x = toPrimitive (x);   if (typeof y === "object" ) y = toPrimitive (y);   if (typeof y === typeof x) return y === x;  // конвертируем x и y в числа, если они еще не используют трюк +   if (typeof x! == "number" ) x = + x;   if (typeof y! == "number" ) y = + y;   // фактически реальный `==` еще более сложный, чем это, особенно в ES6   return x === y; } функция toPrimitive (obj) {   var value = obj.valueOf();   if (obj! == value) возвращаемое значение;   return obj.toString(); } Код> 

Отже, що це значить?

Це означає, що == є складним.

Оскільки це складно, важко зрозуміти, що станеться, коли ви його використовуєте.

Це означає, що у вас можуть бути помилки.

Отже, мораль цієї історії ...

Зробіть ваше життя менш складною.

Використовуйте === замість == .

Кінець.

68
09 авг. відповідь дан Luis Perez 09 Серпня. 2016-08-09 19:50 '16 о 19:50 2016-08-09 19:50

Схема послідовності виконання Javascript для суворого рівності / Порівняння '==='

2019

05 сент. відповідь дан Samar Panda 05 сент. 2015-09-05 16:53 '15 о 16:53 2015-09-05 16:53

JavaScript === vs == .

 0==false // true 0===false // false, because they are of a different type 1=="1" // true, auto type coercion 1==="1" // false, because they are of a different type 
52
03 июля '13 в 7:08 2013-07-03 07:08 відповідь дан user2496033 03 липня '13 в 7:08 2013-07-03 7:08

Це означає рівність без примусу типу тип примусу означає, що JavaScript не автоматичне конвертує будь-які інші типи даних в рядкові типи даних.

 0==false // true,although they are different types 0===false // false,as they are different types 2=='2' //true,different types,one is string and another is integer but javaScript convert 2 to string by using == operator 2==='2' //false because by using === operator ,javaScript do not convert integer to string 2===2 //true because both have same value and same types 
51
12 мая '10 в 15:59 2010-05-12 15:59 відповідь дан Pop Catalin 12 травня '10 о 15:59 2010-05-12 15:59

У типовому script НЕ буде різниці в продуктивності. Більш важливим може бути той факт, що тисяча "===" становить 1 кілобайт важче, ніж тисячі "==" :) профіліровщики JavaScript , може сказати вам, чи є продуктивність різниця в вашому випадку.

Але особисто я б зробив те, що пропонує JSLint. Ця рекомендація існує не через проблеми з продуктивністю, а через обмеження типу ('\t\r\n' == 0) .

46
16 дек. відповідь дан Constantin 16 дек. 2008-12-16 17:29 '08 о 17:29 2008-12-16 17:29

Оператор рівного порівняння == заплутаний, і його слід уникати.

Якщо ви живете з МАЄТЕ, пам'ятайте наступні 3 речі:

  • Він не є транзитивним: (a == b) і (b == c) не призводить до (a == c)
  • Він взаємно виключає його заперечення: (a == b) і (a! = B) завжди мають протилежні булеві значення з усіма a і b.
  • У разі сумнівів вивчіть напам'ять наступну таблицю істинності:

ТАБЛИЦЯ ПРАВИЛЬНОГО ОПЕРАТОРА В JAVASCRIPT

  • Кожен рядок в таблиці являє собою набір з 3 взаємно "рівних" значень, що означає, що будь-які 2 значення з них рівні з використанням знака рівного == *

** STRANGE: зверніть увагу, що будь-які два значення в першому стовпці не рівні в цьому сенсі. **

 '' == 0 == false // Any two values among these 3 ones are equal with the == operator '0' == 0 == false // Also a set of 3 equal values, note that only 0 and false are repeated '\t' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\r' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- '\t\r\n' == 0 == false // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- null == undefined // These two "default" values are not-equal to any of the listed values above NaN // NaN is not equal to any thing, even to itself. 
42
16 сент. відповідь дан CuongHuyTo 16 сент. 2011-09-16 17:25 '11 о 17:25 2011-09-16 17:25

Навряд чи буде якась різниця в продуктивності між двома операціями в вашому використанні. Немає ніякого перетворення типу, яке має бути виконано, тому що обидва параметри вже одного типу. Обидві операції матимуть порівняння типів, за якими слід порівняння значень.

35
11 дек. відповідь дан Sean 11 дек. 2008-12-11 17:44 '08 о 17:44 2008-12-11 17:44

Так! Це має значення.

=== оператор в javascript перевіряє значення, а також тип, де оператор == просто перевіряє значення (при необхідності перетворює тип).

2019

35
14 нояб. відповідь дан Aniket Thakur 14 нояб. 2014-11-14 09:02 '14 в 9:02 2014-11-14 9:02
оператор

=== перевіряє значення, а також типи змінних для рівності.

оператор

== просто перевіряє значення змінних для рівності.

32
12 мая '10 в 16:03 2010-05-12 16:03 відповідь дан Niraj CHoubey 12 травня '10 о 16:03 2010-05-12 16:03

Це строгий контрольний тест.

Це добре, особливо якщо ви перевіряєте між 0 і false і null.

Наприклад, якщо у вас є:

 $a = 0; 

тоді:

 $a==0; $a==NULL; $a==false; 

Все повертає true, і ви можете не хотіти цього. Припустимо, що у вас є функція, яка може повернути 0-й індекс масиву або false при помилці. Якщо ви встановите прапорець з "==" false, ви можете отримати заплутаний результат.

Отже, з тим же, що і вище, але строгий тест:

 $a = 0; $a===0; // returns true $a===NULL; // returns false $a===false; // returns false 
30
12 мая '10 в 16:19 2010-05-12 16:19 відповідь дан Daniel 12 травня '10 о 16:19 2010-05-12 16:19

JSLint іноді дає нереалістичні причини для зміни матеріалу. === має ту ж продуктивність, що і == , якщо типи вже збігаються.

Це швидше, тільки якщо типи не збігаються, і в цьому випадку він не намагається конвертувати типи, але повертає false.

Отже, IMHO, JSLint, можливо, використовується для написання нового коду, але марну надмірну оптимізацію слід уникати будь-яку ціну.

Сенс, немає ніяких причин для зміни == до === в тесті, наприклад if (a == 'test') , коли ви це знаєте, оскільки факт може бути тільки String.

Модифікація великої кількості коду таким чином забирає час розробників і рецензентів і нічого не досягає.

29
05 июня '12 в 10:53 2012-06-05 10:53 відповідь дан ashes 05 червня '12 о 10:53 2012-06-05 10:53

просто

== означає порівняння між операндами з type conversion

=== означає порівняння між операндами без type conversion

Перетворення типів в javaScript означає, що javaScript автоматично перетворює будь-які інші типи даних в рядкові типи даних.

наприклад:

 123=='123' //will return true, because JS convert integer 123 to string '123' //as we used '==' operator 123==='123' //will return false, because JS do not convert integer 123 to string //'123' as we used '===' operator 
28
20 марта '15 в 8:05 2015-03-20 08:05 відповідь дан Amit 20 березня '15 о 8:05 2015-03-20 8:05

Простим прикладом є

 2 == '2' -> true, values are SAME because of type conversion. 2 === '2' -> false, values are NOT SAME because of no type conversion. 
25
14 мая '15 в 17:45 2015-05-14 17:45 відповідь дан Vikas 14 травня '15 о 17:45 2015-05-14 17:45

Топ-2 відповідей на обидва згаданих == означає рівність і === означає ідентифікатор. На жаль, це твердження не так.

Якщо обидва операнда з == є об'єктами, то їх порівнюють, щоб побачити, чи є вони одним і тим же об'єктом. Если оба операнда указывают на один и тот же объект, то оператор равенства возвращает true. В противном случае, они не равны.

 var a = [1, 2, 3]; var b = [1, 2, 3]; console.log(a == b) // false console.log(a === b) // false