From a6b0e92ea3d90e0176532993d7b521aed7135d1b Mon Sep 17 00:00:00 2001 From: Vodimed <67785939+Kim-R2O@users.noreply.github.com> Date: Thu, 11 Feb 2021 15:15:48 +0000 Subject: [PATCH 1/3] =?UTF-8?q?Add=20BigInt=20to=20JS=20=E2=80=9CEquality?= =?UTF-8?q?=20comparisons=20and=20sameness=E2=80=9D=20table=20(#2285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/mdn/content/issues/2237 --- .../index.html | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/files/en-us/web/javascript/equality_comparisons_and_sameness/index.html b/files/en-us/web/javascript/equality_comparisons_and_sameness/index.html index deb72033bc02848..1c2e55268fe6a67 100644 --- a/files/en-us/web/javascript/equality_comparisons_and_sameness/index.html +++ b/files/en-us/web/javascript/equality_comparisons_and_sameness/index.html @@ -74,7 +74,7 @@
true
true
false
false
false
false
false
false
false
false
A === ToNumber(B)
A === ToNumber(B)
A == ToPrimitive(B)
ℝ(A) = ℝ(B)
A === B
ToNumber(A) === ToNumber(B)
A == ToPrimitive(B)
StringToBigInt(A) === B
ToNumber(A) === ToNumber(B)
A === B
ToNumber(A) == ToPrimitive(B)
ToNumber(A) == B
ToPrimitive(A) == B
ToPrimitive(A) == ToNumber(B)
A === B
ToPrimitive(A) == B
false
false
ℝ(A) = ℝ(B)
A === StringToBigInt(B)
A == ToNumber(B)
A == ToPrimitive(B)
A === B
JavaScript provides three different value-comparison operations:
In ES5, the comparison performed by ==
is described in Section 11.9.3, The Abstract Equality Algorithm. The ===
comparison is 11.9.6, The Strict Equality Algorithm. (Go look at these. They're brief and readable. Hint: read the strict equality algorithm first.) ES5 also describes, in Section 9.12, The SameValue Algorithm for use internally by the JS engine. It's largely the same as the Strict Equality Algorithm, except that 11.9.6.4 and 9.12.4 differ in handling {{jsxref("Number")}}s. ES2015 proposes to expose this algorithm through {{jsxref("Object.is")}}.
In ES5, the comparison performed by ==
is described in Section 11.9.3, The Abstract Equality Algorithm. The ===
comparison is 11.9.6, The Strict Equality Algorithm. (Go look at these. They're brief and readable. Hint: read the strict equality algorithm first.) ES5 also describes, in Section 9.12, The SameValue Algorithm for use internally by the JS engine. It's largely the same as the Strict Equality Algorithm, except that 11.9.6.4 and 9.12.4 differ in handling {{jsxref("Number")}}s. ES2015 proposes to expose this algorithm through {{jsxref("Object.is")}}.
We can see that with double and triple equals, with the exception of doing a type check upfront in 11.9.6.1, the Strict Equality Algorithm is a subset of the Abstract Equality Algorithm, because 11.9.6.2–7 correspond to 11.9.3.1.a–f.
@@ -444,14 +444,14 @@In general, the only time {{jsxref("Object.is")}}'s special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors, when it is desirable for your work to mirror some of the characteristics of {{jsxref("Object.defineProperty")}}. If your use case does not require this, it is suggested to avoid {{jsxref("Object.is")}} and use ===
instead. Even if your requirements involve having comparisons between two {{jsxref("NaN")}} values evaluate to true
, generally it is easier to special-case the {{jsxref("NaN")}} checks (using the {{jsxref("isNaN")}} method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.
In general, the only time {{jsxref("Object.is")}}'s special behavior towards zeros is likely to be of interest is in the pursuit of certain meta-programming schemes, especially regarding property descriptors, when it is desirable for your work to mirror some of the characteristics of {{jsxref("Object.defineProperty")}}. If your use case does not require this, it is suggested to avoid {{jsxref("Object.is")}} and use ===
instead. Even if your requirements involve having comparisons between two {{jsxref("NaN")}} values evaluate to true
, generally it is easier to special-case the {{jsxref("NaN")}} checks (using the {{jsxref("isNaN")}} method available from previous versions of ECMAScript) than it is to work out how surrounding computations might affect the sign of any zeros you encounter in your comparison.
Here's a non-exhaustive list of built-in methods and operators that might cause a distinction between -0
and +0
to manifest itself in your code:
- (unary negation)
- (unary negation)
let stoppingForce = obj.mass * -obj.velocity;@@ -472,15 +472,15 @@
-0
return value out of these methods in some cases where a -0
exists as one of the parameters. E.g., Math.min(-0, +0)
evaluates to -0
. Refer to the documentation for the individual methods.~
<<
>>
~
<<
>>
-0
will not survive a round trip after an inverse operation. E.g., both Object.is(~~(-0), -0)
and Object.is(-0 << 2 >> 2, -0)
evaluate to false
.Relying on {{jsxref("Object.is")}} when the signedness of zeros is not taken into account can be hazardous. Of course, when the intent is to distinguish between -0
and +0
, it does exactly what's desired.
The {{jsxref("Object.is")}} specification treats all instances of {{jsxref("NaN")}} as the same object. However, since typed arrays are available, we can have distinct instances, which don't behave identically in all contexts. For example:
From e86c80cf76dc60a2d34e3a40c5eb1bd4ec334ad0 Mon Sep 17 00:00:00 2001 From: "Michael[tm] Smith"In the above table, ToNumber(A)
attempts to convert its argument to a number before comparison. Its behavior is equivalent to +A
(the unary + operator). ToPrimitive(A)
attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString
and A.valueOf
methods on A
.
In the above table:
+ToNumber(A)
attempts to convert its argument to a number before comparison. Its behavior is equivalent to +A
(the unary + operator).ToPrimitive(A)
attempts to convert its object argument to a primitive value, by invoking varying sequences of A.toString
and A.valueOf
methods on A
.ℝ(A)
attempts to convert its argument to an ECMAScript mathematical value.StringToBigInt(A)
attempts to convert its argument to a BigInt
by applying the ECMAScript StringToBigInt
algorithm.Traditionally, and according to ECMAScript, all objects are loosely unequal to undefined
and null
. But most browsers permit a very narrow class of objects (specifically, the document.all
object for any page), in some contexts, to act as if they emulate the value undefined
. Loose equality is one such context: null == A
and undefined == A
evaluate to true if, and only if, A is an object that emulates undefined
. In all other cases an object is never loosely equal to undefined
or null
.