Strict equality in javascript

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:

Alt Text

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

Оцените статью