
After the New Year holidays, I already
suggested to the community to warm up with puzzling situations in JavaScript. Since that post, a decent amount of time has passed, there have been many other holidays, so I suggest we think about a new portion of the tasks.
Answers and my own explanation of why this behavior is logical, like last time, I will hide under the spoiler. Immediately make a reservation that I do not pretend to the unshakable truth of my versions and I will be glad to discuss them. An excellent
Russian translation of the ECMAScript 5 specification can help you to solve this
problem , for which many thanks
iliakan !
1. The main question of life, the universe and all that.
"3" -+-+-+ "1" + "1" / "3" * "6" + "2"
Decision "3" -+-+-+ "1" + "1" / "3" * "6" + "2" == "42"
As we already know from the last post, the β+β operator performs either string concatenation, addition, or coercion to a number. Those.
β3β + 2 == β32β
not 5, as one might think.
')
In addition, you can throw a unary β+β or β-β operator on an expression to change its sign and make things more beautiful and readable.
With all this in mind:
+ β1β === 1 -+ β1β === -1 +-+ β1β === -1 β¦ -+-+-+ === -1 "3" -+-+-+ "1" === 2
Then we recall the priority of operations: / * +
β1β/β3β === 0.3333β¦ β1β / β3β * β6β === 2 2 + 2 === 4 4 + β2β === β42β
2. Maximalism
Math.max(3, 0); Math.max(3, {}); Math.max(3, []); Math.max(-1, [1]); Math.max(-1, [1, 4]); Math.max(3, true); Math.max(3, 'foo'); Math.max(-1, null); Math.max(-1, undefined);
Decision Math.max(3, 0);
It's simple.
Math.max(3, {});
try to execute
toNumber for {}:
let's execute
valueOf and check whether it is primitive - no, then
execute
toString and get
"[object Object]" ;
execute the resulting string
toNumber and get
NaN ;
in the case of obtaining
NaN, Math.max () always returns
NaN .
Math.max(3, []);
try to execute
toNumber for []:
let's execute
valueOf and check whether it is primitive - no, then
run
toString and get "";
execute the resulting string
toNumber and get 0;
3> 0
Math.max(-1, [1]);
Try to execute
toNumber for [1]:
let's execute
valueOf and check whether it is primitive - no, then
execute
toString and get "1";
execute the resulting string
toNumber and get 1;
-1 <1
Math.max(-1, [1, 4]);
try to execute
toNumber for [1,4]:
let's execute
valueOf and check whether it is primitive - no, then
execute
toString and get "1,4";
execute the resulting string
toNumber and get
NaN ;
in the case of obtaining
NaN, Math.max () always returns
NaN .
Math.max(3, true);
try to execute
toNumber for
true :
let's execute
valueOf and check whether it is primitive - yes, then
toNumber(true) === 1
3> 1
Math.max(3, 'foo');
for 'foo'
toNumber returns
NaN .
In the case of getting
NaN, Math.max () always returns
NaN .
Math.max(-1, null);
toNumber(null) === 0 -1 < 0
Math.max(-1, undefined);
toNumber(undefined) === NaN
in the case of obtaining
NaN, Math.max () always returns
NaN .
3. Life comma
[,,,].join() [,,,undefined].join()
Hidden text [,,,].join()
Here I can only refer to Flanagan. 7.1:
βIf an array literal contains several consecutive commas with no values ββbetween them, a sparse array is created. The elements corresponding to these missing values ββare missing in the array, but returning to them returns the value undefined. β
"The syntax of array literals allows you to insert an optional trailing comma."
Why is this done I do not understand.
In comments to the last post it was presented as a feature. In my opinion, this is still a browser crutch from errors in the code.
4. Treasure Map
Array(20).map(function(elem) { return 'a'; });
Hidden text Array(20).map(function(elem) { return 'a'; });
Calling the
Array constructor with one argument creates not an array of 20 elements, but an array whose length is 20. And the
map method first creates an empty array whose length equals the length of the passed array, and then calls a callback for each element of the passed array. In our case, the array has no elements and the method returns an empty array of the same length as the original one.
5. Finita la comedia
isFinite(42); isFinite(1/0); isFinite(0/0); isFinite('42'); isFinite('hi'); isFinite(); isFinite(undefined); isFinite(null);
Hidden text isFinite(42);
isFinite leads the argument to a number, and if
NaN, + Infinity or
-Infinity is obtained , it returns
false . In all other cases,
true .
ToNumber from 'hi' returns
NaN ,
undefined returns
NaN , and
null returns 0.
6. True story bro
'true' == true
Hidden text 'true' == true
The equality operator will sequentially lead to numbers, first true, then 'true'. It turns out NaN == 1, which is obviously false.
7. Nothingness
null == false !null
Hidden text null == false
With
null reduction to
bool, everything is clear. We will understand the comparison. the combination of
null and
bool does not fall under any of the comparison / coercion options in clause 11.9.3 of the specification and therefore the comparison returns
false .
8. Testing uncertainty
/^[az]{1,10}$/.test(null); /^[az]{1,10}$/.test(undefined);
Hidden text /^[az]{1,10}$/.test(null);
Null and
undefined are
cast to the string as is: βnullβ and βundefinedβ - and such strings satisfy the regular expression. And
NaN , by the way, will also become "NaN".
9. Negation of zero
0 === -0 1/0 === 1/-0
Hidden text 0 === -0
Zero is equal to negative zero, but when dividing with a sign, the sign is taken into account and it turns out
Infinity === -Infinity
For those heroes who read to the end, perhaps the most interesting task. I do not want to hide the explanation under another spoiler, so I advise after you give an answer, open devtools and check there. It is likely that the result will surprise you and you will want to think again.
10. Slash
n = 1 /1*"\/\//.test(n + '"
Hidden text n = 1 /1*"\/\//.test(n + '"
Slash can be used in three cases: regular expression, division, and comment. Here, at first glance, we see only the regular expression. But, in fact, without a semicolon, the first slash performs a division. Thus, the first division is performed, and then the result is multiplied by the string. The remaining tail is just a comment. The string by which we multiply to the number is not given and it turns out
NaN .