文章加密

;

2024年7月23日 星期二

const numbers = [33, 2, 8]; numbers.sort(); //[2, 33, 8]

quiz:

const numbers = [33, 2, 8]; 

numbers.sort();  //[2, 33, 8]


Solution:

JavaScript is a dynamically typed language, which means that all standard library functionality must, at some point, decide how to work for most, if not all, use-cases.

Always keep in mind that the following array is valid:

const array = ["1", true, 55, 1.421, "foo", {}];


Array.prototype.sort now needs to make a decision on how to handle such scenarios, and the solution is pretty straight-forward:

Convert all values to their string representation (because every value in JavaScript can always be converted to a string!), and then sort them in lexicographic order(字典順序).

Which basically makes sort see the array as this:

const intermediate = ["33", "2", "8"];


And in lexicographic order, no matter how many characters a string has, comparison starts at position 0, and "3" comes before "8".

And in the end, the result is this:

["2", "33", "8"];

console.log(3 > 2 > 1); // false

 console.log(3 > 2 > 1); // false


因為

先比較 3>2 // true

後比較 true > 1

根據之前提及的 coercion變成Boolean(true) > 1 // false



[陷阱] console.log(typeof typeof 1); // string

 console.log(typeof typeof 1); // string


This actually returns "string".

This expression is evaluated from right to left.

The first sub-expression evaluated actually is typeof 1 which will return "number".

Only after that the next sub-expression is evaluated which now is typeof "number" which returns "string".

[陷阱]console.log("This is a string." instanceof String); // false

 console.log("This is a string." instanceof String); // false


This actually returns false.

The reason for that circumstance is that JavaScript distinguishes between primitives and objects.

And "This is a string." is actually a primitive string and not an instance of the object String.

If the code was like this:

new String("This is a string.") instanceof String


you'd actually get the result you would have expected at the beginning.

What instanceof actually does is checking if the String constructor is nested within the prototype chain of the value provided.

In this case, it isn't.

++{String}, prefix-operator, converting the right-side argument to a number

 The plus operator is defined for numbers and strings and as soon as a string is present on either the left or right side, a string concatenation is perfomed.


If we follow the execution path, this is what happens:

// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' // wait a second!

There are two plus operators in this expression. But one of those is actually a prefix-operator, and not a classical plus.
What it does is converting the right-side argument to a number
, but converting 'a' to a number will actually yield NaN!
Let's continue with following the execution path:

// 1st step
'b' + 'a' -> 'ba'
// 2nd step
'ba' + + 'a' -> 'ba' + NaN -> 'baNaN'
// 3rd step
'baNaN' + 'a' -> 'baNaNa'
// 4th step
'baNaNa'.toLowerCase() -> 'banana'

[有未看]the abstract equality comparison algorithm, which is also called the type-coercing equality check.

quiz:

// 1st step
false == '0'

// 2nd step
Number(false) == '0' -> 0 == '0'

// 3rd step 0 == '0' -> 0 == Number('0')

// 4th step
0 == 0 -> 0 === 0 -> true


solution:

there is a hierarchy for type coercion in JavaScript. The coercion process follows a set of rules:

  1. If either operand is a null or undefined, they are considered equal (unless strict equality is being used with the "===" operator).
    先檢查是否null或undefined
  2. If either operand is a boolean, the boolean is converted to a number (false becomes 0, true becomes 1) before comparison.
    布林值轉數字
  3. If one operand is a string and the other is a number, the string is converted to a number before comparison.
    字串和數字比的話,字串轉數字
  4. If one operand is an object and the other is a primitive value, the object is converted to its primitive value before comparison. This can be done using the valueOf() or toString() methods of the object.
  5. If the operands are both strings, they are compared as strings.
後兩個比較深,先跳過

small quiz

 console.log(typeof NaN); // number

console.log(Number([])); // 0

console.log(Number(![])); // 0

console.log(Number([2])); // 2

console.log(Number([0,0])); // NaN


**

undefined means this thing has no value for some reason. Most of the times you encounter undefined it means that something has gone wrong.

On the other hand, null means this thing has no value, I recognise this and it's the way I would like it to be. 看見null表示是編寫者故意設的

typeof(undefined)Should output ← "undefined"
typeof(null)Should output ← "object"
This is regarded by many as a mistake in the language.
It's too late to fix it now so we'll have to deal with it.