-
Notifications
You must be signed in to change notification settings - Fork 22.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor “Loose equality using ==” #4133
Refactor “Loose equality using ==” #4133
Conversation
This change refactors the entire “Loose equality using ==” section in the “Equality comparisons and sameness” article — with the goal of improving its usability, and at the same time fixing some technical problems with it. * Split the giant loose-equality table into a series of individual tables * Use &nsbp; in comparison formulas, to prevent bad/ugly breaks that otherwise occur in the tables. * Remove all the style attributes from the loose-equality tables (they are unnecessary, and we’d not be able to have styles in it when we move the table source to being markdown). * Make it explicit that the comparisons are to the number, bigint, and string *primitives* — not their corresponding objects. (Otherwise, especially because it has Number, BigInt, String, and Boolean in titlecase, it looked like it was about the objects, not the primitives). * Remove unnecessary redundancy/over-emphasis about comparisons to undefined and null: It’s simple: undefined == null is true, but undefined or null loosely compared to anything else is false – other than the one exception of document.all, which we deal with in prose. * Update the accompanying example to include bigint, and to remove unnecessary and distracting null and undefined comparisons (obviously new String('0') == null and new String('0') == undefined are false; we don’t need to show an example of that).
Thanks for this! I ran out of time today but will take a look tomorrow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sideshowbarker ! I must admit I kind of ran out of steam with this page over in #4118, so I'm really happy to see your PR, which is a vast improvement.
I had a few comments/questions.
<table class="standard-table"> | ||
<thead> | ||
<tr> | ||
<td>number</td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be <th>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be
<th>
?
Indeed yes. Changed them and pushed
</thead> | ||
<tbody> | ||
<tr> | ||
<td><code>ℝ(A) = ℝ(B)</code></td> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why this one (and some other instances further down) seem to be using assignment. AIUI these should all be ===
or am I confused?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<td><code>ℝ(A) = ℝ(B)</code></td>
I'm not sure why this one (and some other instances further down) seem to be using assignment. AIUI these should all be
===
or am I confused?
That’s actually verbatim from step 13 of the “Abstract Equality Comparison” algorithm in the ES spec at https://tc39.es/ecma262/#sec-abstract-equality-comparison:
- If Type(x) is BigInt and Type(y) is Number, or if Type(x) is Number and Type(y) is BigInt, then:
- a. If x or y are any of NaN, +∞𝔽, or -∞𝔽, return false.
- b. If ℝ(x) = ℝ(y), return true; otherwise return false.
So I think it’s kind of inherently confusing outside of reading it in context the algorithm in the spec — where it’s more clear that it’s an equality comparison, not an assignment operation. But I think it might be wrong to change is to ===
in MDN, because the operation being performed there isn’t a JavaScript operation on JavaScript operands but instead an spec-internally-defined operation on spec constructs (“mathematical values” https://tc39.es/ecma262/#mathematical-value).
Anyway, I’ve now pushed a change to replace it with ℝ(x) equals ℝ(y)
. That looks a bit odd but it seems better than keeping ℝ(x) = ℝ(y)
as-is and continuing to confuse everybody — and also better than ℝ(x) === ℝ(y)
, which I’m not sure would be correct (for the reason explained above).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW: Perhaps the triple-bar for identity would have been another option: https://en.wikipedia.org/wiki/Equals_sign#Related_symbols
To me as Mathematician, ℝ reads as the „domain of real numbers” (which includes positive and negative infinity, which are excluded in the definition used by TC39 hier).
But I'm not sure, whether I understand the spec hier correctly.
files/en-us/web/javascript/equality_comparisons_and_sameness/index.html
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/equality_comparisons_and_sameness/index.html
Outdated
Show resolved
Hide resolved
files/en-us/web/javascript/equality_comparisons_and_sameness/index.html
Outdated
Show resolved
Hide resolved
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
980e5b4
to
7583784
Compare
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
Preview URLsFlawsURL: No flaws! 🎉 External URLsURL: |
Will, thanks much for the detailed review — I think it’s resulted in some significant improvements. I believe I’ve responded to all the review comments, so this is back to you now for re-review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarifications @sideshowbarker and for dismembering this monster table!
With this I think there are now no |
w00t — nice work 🎉 |
This change refactors the entire “Loose equality using ==” section in the “Equality comparisons and sameness” article — with the goal of improving its usability, and at the same time fixing some technical problems with it.
Split the giant loose-equality table into a series of individual tables
Use
&nsbp;
in comparison formulas, to prevent bad/ugly breaks that otherwise occur in the tables.Remove all the style attributes from the loose-equality tables (they are unnecessary, and we’d not be able to have styles in it when we move the table source to being markdown).
Make it explicit that the comparisons are to the number, bigint, and string primitives — not their corresponding objects. (Otherwise, especially because it has Number, BigInt, String, and Boolean in titlecase, it looked like it was about the objects, not the primitives).
Remove unnecessary redundancy/over-emphasis about comparisons to undefined and null: It’s simple:
undefined == null
is true, but undefined or null loosely compared to anything else is false – other than the one exception of document.all, which we deal with in prose.Update the accompanying example to include bigint, and to remove unnecessary and distracting null and undefined comparisons (obviously
new String('0') == null
andnew String('0') == undefined
are false; we don’t need to show an example of that).