Vraag Welke gelijk aan operator (== vs ===) moet worden gebruikt in JavaScript-vergelijkingen?


ik gebruik JSLint om JavaScript te gebruiken en er worden veel suggesties teruggestuurd om te vervangen == (twee is gelijk aan tekens) met === (drie is gelijk aan tekens) bij het vergelijken van dingen idSele_UNVEHtype.value.length == 0 binnenkant van een if uitspraak.

Is er een prestatievoordeel te behalen? == met ===?

Elke prestatieverbetering zou worden toegejuicht omdat er veel vergelijkingsoperatoren bestaan.

Als er geen typeconversie plaatsvindt, is er dan sprake van een prestatiewinst ==?


5674
2017-12-11 14:19


oorsprong


antwoorden:


De identiteit (===) exploitant gedraagt ​​zich identiek aan de gelijkheid (==) operator, behalve dat er geen conversie is uitgevoerd, en de typen moeten hetzelfde zijn om als gelijkwaardig te worden beschouwd.

Referentie: Zelfstudie Javascript: Vergelijkingsoperators

De == operator vergelijkt voor gelijkheid na het doen van de nodige typeconversies. De === operator zal niet voer de conversie uit, dus als twee waarden niet van hetzelfde type zijn === zal gewoon terugkeren false. Beide zijn even snel.

Om het uitstekende van Douglas Crockford te citeren JavaScript: de goede delen,

JavaScript heeft twee sets gelijkheidsoperatoren: === en !==en hun slechte tweeling == en !=. De goede werken zoals je zou verwachten. Als de twee operanden van hetzelfde type zijn en dezelfde waarde hebben, dan === produceert true en !== produceert false. De kwade tweelingen doen het goede als de operanden van hetzelfde type zijn, maar als ze van verschillende typen zijn, proberen ze de waarden te dwingen. de regels waarmee ze dat doen zijn gecompliceerd en onmecrebel. Dit zijn enkele van de interessante gevallen:

'' == '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

Het gebrek aan transitiviteit is alarmerend. Mijn advies is om nooit de slechte tweeling te gebruiken. Gebruik in plaats daarvan altijd === en !==. Alle getoonde vergelijkingen produceren false met de === operator.


Bijwerken:

Een goed punt is opgevoed door @Casebash in de reacties en in @Phillipe Laybaert's  antwoord betreffende referentietypen. Voor referentietypen == en === handelt consistent met elkaar (behalve in een speciaal geval).

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

Het speciale geval is wanneer je een letterlijke vergelijkt met een object dat naar dezelfde inhoud evalueert, vanwege zijn toString of valueOf methode. Beschouw bijvoorbeeld de vergelijking van een letterlijke string met een stringobject gemaakt door de String constructeur.

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

Hier de == operator controleert de waarden van de twee objecten en keert terug true, maar de === is zien dat ze niet van hetzelfde type zijn en terugkeren false. Welke is juist? Dat hangt echt af van wat je probeert te vergelijken. Mijn advies is om de vraag geheel te omzeilen en gewoon de String constructor om tekenreeksobjecten te maken.

Referentie
http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3


5716
2017-12-11 14:25



De ... gebruiken ==operator (Gelijkheid)

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

De ... gebruiken ===operator (Identiteit)

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

Dit komt omdat het gelijkheidsoperator == voert wel dwang in, wat betekent dat de interpreter impliciet probeert de waarden om te zetten voordat deze worden vergeleken.

Aan de andere kant, de identiteitsoperator === typ geen dwang, en dus worden de waarden niet geconverteerd bij het vergelijken.


988
2018-06-05 19:11



In de antwoorden hier heb ik niets gelezen over wat Gelijk middelen. Sommigen zullen dat zeggen === middelen gelijk en van hetzelfde type, maar dat is niet echt waar. Het betekent eigenlijk dat beide operanden verwijzen naar hetzelfde objectof in geval van waardetypes, hebben dezelfde waarde.

Dus laten we de volgende code nemen:

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

Hetzelfde hier:

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

Of zelfs:

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

Dit gedrag is niet altijd duidelijk. Er zit meer in het verhaal dan gelijk zijn en van hetzelfde type zijn.

De regel is:

Voor waardetypen (nummers):
a === b geeft true als a en b hebben dezelfde waarde en zijn van hetzelfde type

Voor referentietypen:
a === b geeft true als a en b referentie exact hetzelfde object

Voor snaren:
a === b geeft true als a en b zijn beide strings en bevatten exact dezelfde karakters


Strings: het speciale geval ...

Strings zijn geen waardetypes, maar in Javascript gedragen ze zich als waardetypen, dus ze zullen "gelijk" zijn als de karakters in de string hetzelfde zijn en als ze dezelfde lengte hebben (zoals uitgelegd in de derde regel)

Nu wordt het interessant:

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

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

Maar hoe zit het met dit ?:

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

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

Ik dacht dat tekenreeksen zich gedragen als waardetypes? Wel, het hangt er van af wie je het vraagt ​​... In dit geval zijn a en b niet hetzelfde type. a is van het type Object, terwijl b is van het type string. Onthoud gewoon dat het maken van een string-object met behulp van de String constructor maakt iets van type Object dat gedraagt ​​zich als een string meestal.


545
2018-05-05 05:21



Een interessante beeldrepresentatie van de gelijkheidsvergelijking tussen == en ===.

Bron: http://dorey.github.io/JavaScript-Equality-Table/


var1 === var2

Tijdens gebruik === voor het testen van JavaScript-gelijkheid is alles zoals het is. Niets wordt geconverteerd voordat het wordt geëvalueerd.

Equality evaluation of === in JS


var1 == var2

Tijdens gebruik == voor het testen van JavaScript-gelijkheid, sommige   funky conversies vinden plaats.

Equality evaluation of == in JS

Moraal van het verhaal: 

Gebruik === tenzij je het volledig begrijpt   conversies die plaatsvinden met ==.


519
2017-11-28 18:18



Laat me deze raad toevoegen:

Lees bij twijfel de specificatie! 

ECMA-262 is de specificatie voor een scripttaal waarvan JavaScript een dialect is. In de praktijk is het natuurlijk meer van belang hoe de belangrijkste browsers zich gedragen dan een esoterische definitie van hoe iets moet worden afgehandeld. Maar het is nuttig om te begrijpen waarom new String ("a")! == "a".

Laat me alsjeblieft uitleggen hoe je de specificatie moet lezen om deze vraag te verduidelijken. Ik zie dat niemand in dit zeer oude onderwerp een antwoord had voor het zeer vreemde effect. Dus, als u een specificatie kunt lezen, zal dit u in uw beroep enorm helpen. Het is een verworven vaardigheid. Dus laten we doorgaan.

Zoeken naar het PDF-bestand voor === brengt me naar pagina 56 van de specificatie: 11.9.4. De Strict is gelijk aan Operator (===), en na het waden door de specificationalese vind ik:

11.9.6 Het algoritme voor vergelijking van strikte gelijkheid
  De vergelijking x === y, waarbij x en y waarden zijn, produceert waar of vals. Een dergelijke vergelijking wordt als volgt uitgevoerd:
  1. Als Type (x) anders is dan Type (y), retourneert u vals.
  2. Als Type (x) Ongedefinieerd is, keer terug waar.
  3. Als Type (x) Null is, retourneert u waar.
  4. Als Type (x) geen Nummer is, gaat u naar stap 11.
  5. Als x is NaN, terug vals.
  6. Als y is NaN, terug vals.
  7. Als x dezelfde getalswaarde is als y, retourneert u waar.
  8. Als x +0 is en y -0 is, retourneert u waar.
  9. Als x -0 is en y +0 is, retourneert u waar.
  10. Terug vals.
  11. Als Type (x) String is, keer dan terug waar als x en y exact dezelfde reeks tekens zijn (dezelfde lengte en dezelfde tekens in overeenkomstige posities); anders komt u terug vals.
  12. Als Type (x) Boolean is, retourneert u waar als x en y beide zijn waar of allebei vals; anders komt u terug vals.
  13. Terug waar als x en y naar hetzelfde object verwijzen of als ze verwijzen naar objecten die met elkaar zijn verbonden (zie 13.1.2). Anders ga je terug vals.

Interessant is stap 11. Ja, strings worden behandeld als waardetypes. Maar dit verklaart niet waarom new String ("a")! == "a". Hebben we een browser die niet voldoet aan ECMA-262?

Niet zo snel!

Laten we de typen van de operanden controleren. Probeer het zelf uit door ze in te pakken soort van(). ik vind dat nieuwe reeks ("een") is een object en stap 1 wordt gebruikt: return vals als de typen verschillend zijn.

Als je je afvraagt ​​waarom nieuwe reeks ("een") retourneert geen tekenreeks, hoe zit het met het oefenen van het lezen van een specificatie? Veel plezier!


Aidiakapi schreef dit in een reactie hieronder:

Uit de specificatie

11.2.2 De nieuwe operator:

Als Type (constructor) geen Object is, gooi een TypeError-uitzondering.

Met andere woorden, als String niet van het type Object zou zijn, zou het niet met de nieuwe operator kunnen worden gebruikt.

nieuwe retourneert altijd een object, zelfs voor Draad constructeurs. En helaas! De waardesemantiek voor strings (zie stap 11) gaat verloren.

En dit betekent uiteindelijk: new String ("a")! == "a".


250
2018-05-12 12:58



In PHP en JavaScript is het een strikte operator voor gelijkheid. Wat betekent dat het zowel type als waarden zal vergelijken.


93
2017-12-25 11:17



Ik heb dit in Firefox getest met Firebug code als deze gebruiken:

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

en

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

Mijn resultaten (elk vijf keer getest en gemiddeld):

==: 115.2
===: 114.4

Dus ik zou zeggen dat het minuscule verschil (dit is meer dan 100.000 iteraties, onthoud) verwaarloosbaar is. Prestatie is niet een reden om te doen ===. Type veiligheid (nou ja, zo veilig als je in JavaScript krijgt), en codekwaliteit is dat.


88
2018-05-12 12:58



In JavaScript betekent dit van dezelfde waarde en hetzelfde type.

Bijvoorbeeld,

4 == "4" // will return true

maar

4 === "4" // will return false 

84
2017-12-11 14:58



De === operator wordt een strikte vergelijkingsexploitant genoemd doet verschillen van de == operator.

Laten we 2 vars a en b nemen.

Voor "a == b" om te evalueren naar waar a en b moeten de zijn dezelfde waarde.

In het geval van "a === b" a en b moeten de zijn dezelfde waarde en ook de zelfde type om te evalueren naar waar.

Neem het volgende voorbeeld

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");
}

samengevat; de ... gebruiken == operator kan evalueren naar true in situaties waarin u niet wilt dat het zo werkt met de === operator zou veiliger zijn.

In het gebruiksscenario van 90% maakt het niet uit welk apparaat u gebruikt, maar het is handig om het verschil te kennen wanneer u op een dag onverwacht gedrag krijgt.


72
2018-05-12 12:58



Het controleert of dezelfde zijden gelijk zijn type net zoals waarde.

Voorbeeld:

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

Veelvoorkomend voorbeeld:

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

Nog een veelvoorkomend voorbeeld:

null == undefined // returns "true", but in most cases a distinction is necessary

64
2017-09-05 13:53