After the New Year holidays, I already invited the community to stretch their mind at jigsaw puzzles in JavaScript. Quite a lot of time has passed since that post, there have been many other holidays, so I suggest thinking about a new portion of tasks.

I will hide the answers and my own version of the explanation of why this behavior is logical, as last time, 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. The excellent Russian translation of the ECMAScript 5 specification can help you in solving this , for which many thanks iliakan !

##### 1. The main issue 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 concatenation of strings, or addition, or reduction to a number. Those.
``````“3” + 2 == “32”
``````

not 5, as you might think.

In addition, you can throw the unary operator “+” or “-” on an expression to change its sign and make things more beautiful and readable.

Given all of the above:
``````+ “1” === 1
-+ “1” === -1
+-+ “1” === -1
…
-+-+-+ === -1
"3" -+-+-+ "1" === 2  //вычитание производится над числами
``````

Next, 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);           // 3
``````

Everything is simple here.

``````Math.max(3, {});          // NaN
``````

try to execute toNumber for {}:
execute valueOf and check if it is primitive - no, then
execute toString and get "[object Object]" ;
execute for the resulting string toNumber and get NaN ;
if NaN is received, Math.max () always returns NaN .

``````Math.max(3, []);          // 3
``````

let's try to execute toNumber for []:
execute valueOf and check if this is primitive - no, then
execute toString and get "";
execute for the resulting string toNumber and get 0;
3> 0

``````Math.max(-1, [1]);     // 1
``````

we will try to execute toNumber for [1]: we
will execute valueOf and we will check whether it is primitive - no, then we
will execute toString and we will receive "1";
execute for the resulting string toNumber and get 1;
-1 <1

``````Math.max(-1, [1, 4]);  // NaN
``````

try to execute toNumber for [1,4]:
execute valueOf and check if it is primitive - no, then
execute toString and get “1,4”;
execute for the resulting string toNumber and get NaN ;
if NaN is received, Math.max () always returns NaN .

``````Math.max(3, true);        // 3
``````

try to execute toNumber for true :
execute valueOf and check if this is primitive - yes, then
``````toNumber(true) === 1
``````

3> 1

``````Math.max(3, 'foo');       // NaN
``````

for 'foo' toNumber returns NaN .
If NaN is received, Math.max () always returns NaN .

``````Math.max(-1, null);       // 0
``````

``````toNumber(null) === 0
-1 < 0
``````

``````Math.max(-1, undefined);  // NaN
``````

``````toNumber(undefined) === NaN
``````

if NaN is received, Math.max () always returns NaN .

##### 3. Life comma

``````[,,,].join()
[,,,undefined].join()
``````

Hidden text
``````[,,,].join()      // ",,"
[,,,undefined].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. Elements corresponding to such missing values ​​are absent in the array, but when they are accessed, the value is undefined. "
" The syntax of array literals allows you to insert an optional trailing comma. "
Why is this not clear to me. In the comments on the last post, this 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'; }); // Array of undefined x 20
``````

Calling the Array constructor with one argument does not create an array of 20 elements, but an array with a length of 20. And the map method first creates an empty array whose length is equal to the length of the transferred array, and then calls a callback for each element of the transferred array. In our case, the array has no elements and the method returns an empty array of the same length as the original.

##### 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); // true
isFinite(1/0); // false
isFinite(0/0); // NaN is not finite -> false
isFinite('42'); // true
isFinite('hi'); // false
isFinite(); // false
isFinite(undefined); // false
isFinite(null); // true
``````

isFinite converts the argument to a number, and if it turns out NaN, + Infinity or -Infinity , then returns false . In all other cases, true .
ToNumber from 'hi' will return NaN , undefined will return NaN , and null will return 0.

##### 6. True story bro

``````'true' == true
``````

Hidden text
``````'true' == true //false
``````

The equality operator sequentially leads to numbers first true, then 'true'. It turns out NaN == 1, which is obviously false.

##### 7. Nothingness

``````null == false
!null
``````

Hidden text
``````null == false // false
!null // true
``````

With casting null to bool, everything is clear. We will deal with the comparison. the combination of null and bool does not fall under any of the comparison \ cast options in clause 11.9.3 of the specification and therefore the comparison returns false .

##### 8. Uncertainty Testing

``````/^[a-z]{1,10}\$/.test(null);
/^[a-z]{1,10}\$/.test(undefined);
``````

Hidden text
``````/^[a-z]{1,10}\$/.test(null);  //true
/^[a-z]{1,10}\$/.test(undefined);  //true
``````

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        //true
1/0 === 1/-0    //false
``````

Zero is negative zero, but when dividing with a sign, the sign is taken into account and it turns out
``````Infinity === -Infinity
``````

For those heroes who have read to the end, perhaps the most interesting puzzle. I do not want to hide the explanation under another spoiler, so I advise you after you give the 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 + '"//')
n = 1;
/1*"\/\//.test(n + '"//');
``````

Hidden text
``````n = 1
/1*"\/\//.test(n + '"//')  //NaN
n = 1;
/1*"\/\//.test(n + '"//');  //true
``````

A slash can be used in three cases: regular expression, division, and comment. Here, at first glance, we see only a regular expression. But, in fact, without a semicolon, the first slash performs division. Thus, division is first performed, and then the result is multiplied by a string. The remaining tail remains just a comment. The line by which we multiply to the number is not reduced and NaN is obtained .