- Equality & strict-Equality Operators in javaScript
- ‘===’ is -strict equality- operator:
- Strict/no-strict Equality Performance:
- Performance study case:
- Strict/no-strict Equality Differences:
- Why
- Strict/no-strict Equality Case studies:
- Reason:
- Why?
- Quick way to compare:
- Done?
- We need to use a deep comparison:
- The base implementation of _.isEqual which supports partial comparisons * and tracks traversed objects.
- Conclusion level 6:
- Extra take-away recomendation:
- Strict equality (===)
- Try it
- Syntax
- Description
- Examples
- Comparing operands of the same type
- Comparing operands of different types
- Comparing objects
- Specifications
- Browser compatibility
- See also
- Found a content problem with this page?
- MDN
- Support
- Our communities
- Developers
Equality & strict-Equality Operators in javaScript
1) Compares if the operands are of the «same type» and have the «same value».
2) If they have «different type» we will «coerce/convert type» and then evaluate again.
‘===’ is -strict equality- operator:
1) Compares if the operands are of the «same type» and have the «same value».
2) If they are «different type» = are different.
We DON’T doing any «type conversions»
Strict/no-strict Equality Performance:
‘==’ Coerce the value, this longer with sometimes unexpected results
‘===’ Don’t coerce, and takes short time
Performance study case:
const arr1 = ['a', 'b', 'c', 'd', 'e']; console.time('time'); const arr2 = arr1.map(item => if(item == 'c') // coercing takes a little extra effort item = 'CAT'; > console.timeEnd('time'); return item; >); // ['a', 'b', 'CAT', 'd', 'e'] // time: 0.041015625ms
const arr1 = ['a', 'b', 'c', 'd', 'e']; console.time('time'); const arr2 = arr1.map(item => if(item === 'c') // don't coerce = faster item = 'CAT'; > console.timeEnd('time'); return item; >); // ['a', 'b', 'CAT', 'd', 'e'] // time: 0.02783203125ms
Results:
=== Don’t coerce, and takes short time
0.041015625 > 0.02783203125 = true
Strict/no-strict Equality Differences:
Coercion / Conversion type.
Converting a value from one type to another, this take extra time and some times is not what we expect.
Both are comparing same things. But ‘identical’ will be quicker if type are not the same, because wont’t convert type.
Why
Internally JS has actually two different approaches for testing equality: Primitives like strings and numbers are compared by their value, while objects like arrays, dates, and plain objects are compared by reference. Comparison by reference basically checks to see if the objects given refer to the same location in memory allocation.
1 == "1"; // true (apostrophe) number == string => coerce: get typeof of each operator String(1); // string: course first operand (check operand table) with the second operand type "1" == "1" // wrong true: compared after coerce
Strict/no-strict Equality Case studies:
1) Comparing string literal with a string object created with the string constructor.
"test" == new String("test") // true "test" === new String("test") // false 1 == '1'; // true NaN === null; // false => typeof(NaN) = number typeof(undefined) = '' == 0; // true '' === 0; // false false == 0 // true [] === []; false :( [1,2] === [1,2]; // false :( <> === <>; // false :( typeof(NaN); //number typeof(''); //string typeof(undefined); //undefined "" == 0; // true "" === 0; // false false == '0' // true null == undefined // true 3 == "00003"; // true 3 === "00003"; // false
1) Using null with » combination
null 1 // true 1 2 3 // true 3 2 1 // true
Reason:
2) Using null guard
null:
null is an empty or non-existent value.
null must be assigned: null is an assigned value. It means nothing.
In JS null is «nothing». It is «supposed» to be something that doesn’t exist. Unfortunately, in JS, the data type of ‘null’ is considered an JS object
typeof bar === «object»
var bar = null; console.log(typeof bar === "object"); // logs true! -> null object?
better do
var bar = null; console.log((bar !== null) && (bar.constructor === Object)); // logs false
3) Using typeof obj === «function»
function isObject(obj) return (typeof obj === "object" && obj !== null) || typeof obj === "function"; > // Test: function sumArguments() return Array.from(arguments).reduce((sum, num) => sum + num); > isObject(sumArguments); // true
3) Object Equality in JavaScript
const object = 'a': 1 >; const other = 'a': 1 >; object == other; // false
const object = 'a': 1 >; const other = 'a': 1 >; object === other; // false
Why?
Object and other refer to two objects with identical properties, but they are each distinct instances.
Quick way to compare:
var object = 'a': 1 >; var other = 'a': 1 >; JSON.stringify(object) === JSON.stringify(other); // true
var object = 'a': 1 >; var other = 'a': 1 >; JSON.stringify(object) == JSON.stringify(other); // true
Done?
YAY! happy times JSON.stringify() will do it! . Nop, this method converts objects to strings first and comparison takes place afterwards. Problem is the order of the keys:
var object = 'a': 1, 'b': 2 >; var other = 'b': 2, 'a': 1 >; JSON.stringify(object) == JSON.stringify(other); // false
var object = 'a': 1, 'b': 2 >; var other = 'b': 2, 'a': 1 >; JSON.stringify(object) === JSON.stringify(other); // false
A solution to the JSON.stringify() key order can theoretically resolve converting this ‘Object’ to ‘Array of Object’, and then use Array.prototype.sort() (ES9 sort could be better) and finally JSON.stringify() but we also need to do this process across the whole deep of the nested object. I rather simple face the problem with an alternative approach like using: «Deep’s» Equal, «Lodash’s» isEqual or «Fast’s» Equals. Let’s have a look at the «Lodash’s» solution:
We need to use a deep comparison:
var object = 'a': 1 >; var other = 'a': 1 >; object === other; // => false _.isEqual(object, other); // true
The base implementation of _.isEqual which supports partial comparisons * and tracks traversed objects.
// source: https://github.com/lodash/lodash/blob/4.17.15/lodash.js#L11567 /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param value The value to compare. * @param other The other value to compare. * @param bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param [customizer] The function to customize comparisons. * @param [stack] Tracks traversed `value` and `other` objects. * @returns Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) if (value === other) return true; > if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) return value !== value && other !== other; > return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); >
Conclusion level 6:
Both are comparing same things, but ‘==’ allows coercion, and ‘===’ disallows coercion, making === faster and more accurate. Both ‘==’ and ‘===’ check the types of their operands. The difference is in how they respond if the types don’t match.
Extra take-away recomendation:
Please Avoid ‘==’ operator, can cause potential coerce errors.
Please Use ‘===’ operator, and also make it faster or we «~can» use Object.is()*
// * No support on IE11 only IE12+ Object.is( 1, "1"); // false Object.is('foo', 'foo'); // true Object.is(null, null); // true
Strict equality (===)
The strict equality ( === ) operator checks whether its two operands are equal, returning a Boolean result. Unlike the equality operator, the strict equality operator always considers operands of different types to be different.
Try it
Syntax
Description
The strict equality operators ( === and !== ) provide the IsStrictlyEqual semantic.
- If the operands are of different types, return false .
- If both operands are objects, return true only if they refer to the same object.
- If both operands are null or both operands are undefined , return true .
- If either operand is NaN , return false .
- Otherwise, compare the two operand’s values:
- Numbers must have the same numeric values. +0 and -0 are considered to be the same value.
- Strings must have the same characters in the same order.
- Booleans must be both true or both false .
The most notable difference between this operator and the equality ( == ) operator is that if the operands are of different types, the == operator attempts to convert them to the same type before comparing.
Examples
Comparing operands of the same type
"hello" === "hello"; // true "hello" === "hola"; // false 3 === 3; // true 3 === 4; // false true === true; // true true === false; // false null === null; // true
Comparing operands of different types
"3" === 3; // false true === 1; // false null === undefined; // false 3 === new Number(3); // false
Comparing objects
const object1 = key: "value", >; const object2 = key: "value", >; console.log(object1 === object2); // false console.log(object1 === object1); // true
Specifications
Browser compatibility
BCD tables only load in the browser
See also
Found a content problem with this page?
This page was last modified on Feb 21, 2023 by MDN contributors.
Your blueprint for a better internet.
MDN
Support
Our communities
Developers
Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2023 by individual mozilla.org contributors. Content available under a Creative Commons license.