Types
Typeof operator
Type has some surprising cases that could lead to bugs if carelessly handled
1 | type of doesnotExist; // undefined |
Temporary Dead Zone (TDZ)
undeclared -> uninitialized -> undefined
let variables cannot be read/written until they have been fully initialized, which happens when they are declared
1 | { // TDZ starts at beginning of scope |
This phenomenon can be confusing in a situation like the following.
The instruction let n of n.a is already inside the private scope of the
for loop's block. So, the identifier n.a is resolved to the
property 'a' of the 'n' object located in the first part of the
instruction itself (let n). 1
2
3
4
5
6
7
8
9
10function go(n) {
// n here is defined!
console.log(n); // Object {a: [1,2,3]}
for (let n of n.a) { // ReferenceError
console.log(n);
}
}
go({a: [1, 2, 3]});
NaN & isNaN
NaN is the only value that is not equal to itself
NaN: an invalid number (a number but not valid)
isNaN coerces values to numbers before it checks for them to be NaN
1
2isNaN("8") // false
isNaN("not a number") // true
Number.isNaN() does not coerce 1
2Number.isNaN(Number("test")) // true
Number.isNaN("not a number") // false
Negative 0
1 | -0 === 0; // true |
Fundamental Objects (aka: buit-in objects aka Native Functions)
Don't use them but understand them
Coercion Corner Cases
Be aware about the corner cases and you need to handle it in your code, especially from DOM elements.
String to Number Example 1
2
3
4
5
6
7
8
9
10
11function addAStudent(numStudents) {
// here we need to do coercion
// as plus sign will concatenate string with number
// corner cases of coercion is that
// empty string could be coerced to 0
return numStudents + 1;
}
// + sign will coerce the variable into number
addAStudent (+studentInputElem.value)
A possible validation function for numStudents could be
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// make sure we coerce by excluding corner cases
if(
typeof numStudents == "string" &&
numStudents.trim() != ""
) {
numStudents = Number(numStudents)
}
if(
typeof numStudents == "number" &&
numStudents >= 0 &&
Number.isInteger(numStudents)
) {
return true;
}
return false
String Example
1 | // make sure name string |
Double equal ==
Double equal will work like the following in order: 1. If the types are the same: === 2. If null or undefined: equal 3. If non-primitives: ToPrimitive 4. Prefer: ToNumber
To avoid: * == with 0 or "" (or even " ") * == with non-primitives * == true or == false: allow ToBoolean or use ===