-
-
Save gaearon/08a85a33e3d08f3f2ca25fb17bd9d638 to your computer and use it in GitHub Desktop.
// Your scientists were so preoccupied | |
// with whether or not they could, | |
// they didn't stop to think if they should. | |
// Like a === b | |
function strictEquals(a, b) { | |
if (Object.is(a, b)) { | |
// Same value. | |
// Is this NaN? | |
if (Object.is(a, NaN)) { // We already know a and b are the same, so it's enough to check a. | |
// Special case #1. | |
return false; | |
} else { | |
// They are equal! | |
return true; | |
} | |
} else { | |
// Different value. | |
// Are these 0 and -0? | |
if ( | |
(Object.is(a, 0) && Object.is(b, -0)) || | |
(Object.is(a, -0) && Object.is(b, 0)) | |
) { | |
// Special case #2. | |
return true; | |
} else { | |
// They are not equal! | |
return false; | |
} | |
} | |
} |
Rainer-Yu
commented
Mar 31, 2022
•
function strictEquals(a, b){
return (Object.is(a, NaN) && Object.is(b, NaN))
? false
: (
(Object.is(a, 0) && Object.is(b, -0)) ||
(Object.is(a, -0) && Object.is(b, 0))
)
? true
: Object.is(a, b);
}
I see folks are posting their solutions, so I will post mine too, just for fun :P
function strictEquals(a, b) {
if (Object.is(a, NaN) || Object.is(b, NaN)) {
return false;
}
if (Object.is(a, 0) && Object.is(b, -0)) {
return true;
}
if (Object.is(a, -0) && Object.is(b, 0)) {
return true;
}
return Object.is(a, b);
}
I thought I'd share my 'aha' moment.
My first condition was:
if(isNaN(a) && isNaN(b)) return false;
Which seemed to work just fine, until I tried strictEquals(strictEquals,strictEquals)
just for fun. Result: false
.
So I learned the following fun fact:
isNaN(strictEquals); //true
Number.isNaN(strictEquals); //false
When in doubt, read the docs!. That coercion can be a real Yml0Y2g=.
function strictEqual(a, b) {
if (Object.is(a, b)) {
if (Object.is(a, NaN)) {
return false;
}
return true;
}
if (!Object.is(a, b)) {
if (Object.is(a, 0) && Object.is(b, -0)) {
return true;
}
if (Object.is(a, -0) && Object.is(b, 0)) {
return true;
}
return false;
}
}
console.log(strictEqual(NaN, NaN));
function stringEquals(a, b) {
if (isNaN(a)) return false
if ([0, -0].includes(a) && Object.is(a, -b)) return true
return Object.is(a, b)
}
First special case NaN === NaN => both a and b will be NaN and therefore, and if either value is NaN, should return false. Other case, return the result of Objects.is(a, b)
Second sepecial case 0 === -0 or -0 === 0 => if the a is 0 or -0 and Object.is(a -b), its one of the special situations, that needs to return true. Otherwise, return Object.is(a, b)
const strictEquals = (a, b) => {
if(Number.isNaN(a) || Number.isNaN(b)){
return false;
}
if((a == 0 && b == 0) || (a == -0 && b == -0)){
return true;
}
return Object.is(a,b);
}
Coming late to the party:
function strictEquals(a, b) {
if (Number.isNaN(a) && Number.isNaN(a)) {
return false;
}
if (
typeof a === "number" &&
typeof b === "number" &&
Object.is(Math.abs(a), Math.abs(b))
) {
return true;
}
return Object.is(a, b);
}
function strictEquals(a, b) {
return typeof a == typeof b && a == b
}
seems to be working.
And if it valid seems to be good reason to use double equal
Coming late to the party:
function strictEquals(a, b) { if (Number.isNaN(a) && Number.isNaN(a)) { return false; } if ( typeof a === "number" && typeof b === "number" && Object.is(Math.abs(a), Math.abs(b)) ) { return true; } return Object.is(a, b); }
Check exercise requirements then have a look at your code one more time. You will have a smile on your face :-)
function strictEquals(a, b) {
if (Object.is(a, NaN) && Object.is(b, NaN)) {
return false;
}
if (
(Object.is(a, -0) && Object.is(b, 0)) ||
(Object.is(a, 0) && Object.is(b, -0))
) {
return true;
}
return Object.is(a, b);
}
//mine is similar to others, but I wanted to share anyway :)
`function strictEquals(a, b){
if(Object.is(a, b)){
// they're equal
if(Number.isNaN(a) && Number.isNaN(b)){
//if it is Nan, return false
return false;
}
//else they're equal
return true;
} else {
//if both values are either 0 or -0
if((Object.is(a, 0) || Object.is(a, -0))
&& ((Object.is(b, 0) || Object.is(b, -0)))
){
return true;
} else {
//else they're not equal
return false;
}
}
}`
const strictEquals = (a, b) => {
if ((typeof a).match(/number/) && (typeof b).match(/number/)) {
if (Object.is(a, NaN)) { return false };
if (!a && !b) { return true };
}
return Object.is(a, b);
}
console.assert(strictEquals(NaN, NaN) === false, "strictEquals(NaN,NaN) should be false");
console.assert(strictEquals(0, -0) === true, "strictEquals(0,-0) should be true");
console.assert(strictEquals(-0, 0) === true, "strictEquals(-0,0) should be true");
console.assert(strictEquals(-0, -0) === true, "strictEquals(-0,-0) should be true");
console.assert(strictEquals("dog", "dog") === true, "strictEquals('dog','dog') should be true");
console.assert(strictEquals("dog", "cat") === false, "strictEquals('dog','cat') should be false");
function strictEquals(a,b){
if(Object.is(a.toString(),'NaN') && Object.is(b.toString() ,"NaN")){
return false
}
if((Object.is(a,0) && Object.is(b,-0)) || (Object.is(a,-0) && Object.is(b,0))) {
return true
}
return Object.is(a,b)
}
function strictEquals(a, b) {
if (Object.is(a, NaN) && Object.is(b, NaN)) return false;
if (Object.is(a, -0) && Object.is(b, 0)) return true;
if (Object.is(a, 0) && Object.is(b, -0)) return true;
return Object.is(a, b);
}
Someone above already posted this idea, but this would work if you wanted a single line version:
const strictEquals = (a, b) => typeof a == typeof b && a == b;
A long time ago I remember reading in JavaScript: The Good Parts that == was the "evil twin" of === and that it worked correctly when the values were of the same type, but things got messy when the values were of different types. The take away for me was that === was == but with a type check. Not sure why that stuck with me all these years.
function strictEquals(a, b) {
if (a === NaN && b === NaN) return !Object.is(a, b);
if (a === -0 && b === 0) return !Object.is(a, b);
if (b === -0 && a === 0) return !Object.is(a, b);
return Object.is(a, b);
}
const strictEquals = (a, b) => {
if (Object.is(a, b)) return !Object.is(a, NaN);
return (
(Object.is(a, 0) && Object.is(b, -0)) ||
(Object.is(a, -0) && Object.is(b, 0))
);
};
am I missing something?
function strictEquals(a,b) { // consider below 2 special cases // -0, 0 // NaN NaN if (Object.is(a, NaN) && Object.is(b, NaN)) return false; if (Object.is(a, 0) && Object.is(b, -0)) return true; return Object.is(a, b); }
Your implementation incorrectly returns false
for strictEquals(-0, 0)
const strictEquals = (a, b) => {
if (!Object.is(a, b) && Object.is(a, -b) && Object.is(-a, b)) return true;
if (Number.isNaN(a) && Number.isNaN(b)) return false;
return Object.is(a, b);
};
const strictEquals = (a, b) => { if (!Object.is(a, b) && Object.is(a, -b) && Object.is(-a, b)) return true; if (Number.isNaN(a) && Number.isNaN(b)) return false; return Object.is(a, b); };
@tobias-edwards your implementation won't work for negative-positive check on numbers other than 0. (try -1 === 1)
const strictEquals = (a, b) => { if (!Object.is(a, b) && Object.is(a, -b) && Object.is(-a, b)) return true; if (Number.isNaN(a) && Number.isNaN(b)) return false; return Object.is(a, b); };@tobias-edwards your implementation won't work for negative-positive check on numbers other than 0. (try -1 === 1)
Ah yes, you're right! Thanks. I'll leave my wrong solution to preserve chat integrity
function strictEquals(a: any, b: any) {
if(Number.isNaN(a) && Number.isNaN(b)) return !Object.is(a, b)
if(Object.is(a, 0) && Object.is(b, -0) || Object.is(a, -0) && Object.is(b, 0)) {
return true
}
return Object.is(a, b);
}
const strictEqual = (a, b) => {
if(Number.isNaN(a) && Number.isNaN(b)){
return false
}
else if(Object.is(a, -0) && Object.is(b, 0)) {
return true
}
else if(Object.is(a, 0) && Object.is(b, -0)) {
return true
}
else {
return Object.is(a, b)
}
}
am I missing something?
function strictEquals(a,b) { // consider below 2 special cases // -0, 0 // NaN NaN if (Object.is(a, NaN) && Object.is(b, NaN)) return false; if (Object.is(a, 0) && Object.is(b, -0)) return true; return Object.is(a, b); }
you are not holding the case
if (Object.is(a, -0) && Object.is(b, 0)) return true;
Hi, here is my solution::
const myInfinite = 1/0; // = Infinite
const myCero = 0/myInfinite; // = 0
function stringEquals(a: Number, b: Number){
if(Number.isNaN(a) && Number.isNaN(b))
return false;
if(Object.is(a, myCero) && Object.is(b, -myCero))
return true
if(Object.is(a, -myCero) && Object.is(b, myCero))
return true
return Object.is(a, b);
}
let a, b;
a=1;
b=1;
stringEquals(a,b);
console.log(a===b);
console.log(Object.is(a,b));
a=1;
b=2;
stringEquals(a,b);
console.log(a===b);
console.log(Object.is(a,b));
a=0;
b=0;
stringEquals(a,b);
console.log(a===b);
console.log(Object.is(a,b));
a=NaN;
b=NaN;
stringEquals(a,b);
console.log(a===b);
console.log("It must be different:: ",Object.is(a,b));
a=0;
b=-0;
stringEquals(a,b);
console.log(a===b);
console.log("It must be different:: ",Object.is(a,b));
a=-0;
b=0;
stringEquals(a,b);
console.log(a===b);
console.log("It must be different:: ",Object.is(a,b));
My Function is like this
function strictEquals(a,b) {
if (
(Object.is(a, 0) && Object.is(b, -0)) ||
(Object.is(a, -0) && Object.is(b, 0))
) {
return true;
}
if (Number.isNaN(a) && Number.isNaN(b)){
return false;
}
return Object.is(a,b)
}
console.log(strictEquals(NaN,NaN));
Many already made it.
My version:
function strictEquals(a, b) {
if (Number.isNaN(a) && Number.isNaN(b)) return !Object.is(a, b);
if ((Object.is(a, -0) ^ Object.is(b, -0)) && (Object.is(a, 0) ^ Object.is(b, 0))) return !Object.is(a, b);
return Object.is(a, b);
}
Hope this is the shortest
function strictEquals(a,b){
if(Number.isNaN(a) && Number.isNaN(b)) return false
if(!Object.is(a,b) && Object.is(a+"",b+"")) return true
return Object.is(a,b)
}
function stringEquals(a, b) { if (isNaN(a)) return false if ([0, -0].includes(a) && Object.is(a, -b)) return true return Object.is(a, b) }
First special case NaN === NaN => both a and b will be NaN and therefore, and if either value is NaN, should return false. Other case, return the result of Objects.is(a, b)
Second sepecial case 0 === -0 or -0 === 0 => if the a is 0 or -0 and Object.is(a -b), its one of the special situations, that needs to return true. Otherwise, return Object.is(a, b)
I found it interesting that you managed to shorten if (isNaN(a) && isNaN(b)) return false
to if (isNaN(a)) return false
. You don't need to check if either value is NaN, you have enough with checking if the first value is NaN, in which case it will definitely evaluate to false. And you don't need to care about the remaining case in which b is NaN while a isn't, because Object.is() will handle it perfectly.