Hvilken likhetstegnoperator (== vs ===) skal brukes i JavaScript-sammenligninger?

Jeg bruker JSLint for å gå gjennom JavaScript, og det returnerer mange forslag om å erstatte == (to likhetstegn) med === (tre likhetstegn) når du gjør ting som å sammenligne idSele_UNVEHtype.value.length == 0 inne i en if-setning.

Er det en ytelsesfordel å erstatte == med ===?

Enhver ytelsesforbedring vil være velkommen ettersom det finnes mange sammenligningsoperatorer.

Hvis ingen typekonvertering finner sted, vil det være en ytelsesgevinst i forhold til ==?

Løsning

Identitetsoperatoren (===) oppfører seg identisk med likhetoperatoren (==) bortsett fra at det ikke gjøres noen typekonvertering, og typene må være like for å anses som like.

Referanse: Javascript-veiledning: Sammenligningsoperatorer

Operatoren == vil sammenligne for likhet etter å ha gjort eventuelle nødvendige typekonverteringer. Operatoren === vil ikke gjøre konverteringen, så hvis to verdier ikke er av samme type, vil === bare returnere false. Begge er like raske.

For å sitere Douglas Crockfords utmerkede JavaScript: The Good Parts,

JavaScript har to sett med likhet operatorer: === og !==, og deres onde tvillinger == og !=. De gode fungerer slik du forventer. Hvis de to operandene er av samme type og har samme verdi, gir === sant og !== gir falskt. De onde tvillingene gjør det rette når operandene er av samme type, men hvis de er av forskjellige typer, prøver de å tvinge verdiene. reglene de gjør det etter er kompliserte og umulige å huske. Dette er noen av de interessante tilfellene:

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

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

false == udefinert // false false == null // false null == udefinert // true

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

Mangelen på transitivitet er alarmerende. Mitt råd er å aldri bruke de onde tvillingene. Bruk i stedet alltid === og !==. Alle sammenligningene som nettopp er vist, gir false med ===-operatoren.


Oppdatering:

Et godt poeng ble tatt opp av @Casebash i kommentarene og i @Phillipe Laybaert's svar angående referansetyper. For referansetypene == og === fungerer konsekvent med hverandre (bortsett fra i et spesielt tilfelle).

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

Spesialtilfellet er når du sammenligner en bokstav med et objekt som evaluerer til samme bokstav, på grunn av dens toString eller valueOf metode. Tenk for eksempel på sammenligningen av en strengliteral med et strengobjekt opprettet av String-konstruktøren.

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

Her sjekker ==-operatoren verdiene til de to objektene og returnerer true, men === ser at de ikke er av samme type og returnerer false. Hvilken er riktig? Det kommer virkelig an på hva du prøver å sammenligne. Mitt råd er å omgå spørsmålet helt og bare ikke bruke String-konstruktøren for å lage strengobjekter.

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

Kommentarer (45)

Bruk av ==-operatoren (Likhet)

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

Bruke ===-operatoren (Identitet)

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

Dette er fordi likhetsoperatoren == skriver tvang, noe som betyr at tolkeren implisitt prøver å konvertere verdiene før sammenligning.

På den annen side gjør identitetsoperatoren === ikke typetvang, og konverterer dermed ikke verdiene ved sammenligning, og er derfor raskere (i henhold til This JS benchmark-testen) ettersom den hopper over ett trinn.

Kommentarer (5)

Det er usannsynlig at det vil være noen ytelsesforskjell mellom de to operasjonene i din bruk. Det er ingen typekonvertering som skal gjøres fordi begge parametrene allerede er av samme type. Begge operasjonene vil ha en typesammenligning etterfulgt av en verdisammenligning.

Kommentarer (0)