# Session 6: Quirky Topics
[slide online](https://hackmd.io/@e8KGkGmbTPWKGH_D_dy9DA/Bk0U-ppDo)
---
## Type casting
### Numbers > `+` operator
```javascript
const initial = "1.2";
const converted = +initial;
console.log(typeof initial); // String
console.log(typeof converted); // Number
console.log(converted); // 1.2
```
---
## Type casting
### Numbers > `+` operator
```javascript
const nanInitial = "1.2whatever";
const converted = +nanInitial;
console.log(typeof converted); // Number
console.log(converted); // NaN
```
---
## Type casting
### Numbers > `Number()`
```javascript
const initial = "1.2";
const converted = Number(initial);
console.log(typeof initial); // String
console.log(typeof converted); // Number
console.log(converted); // 1.2
```
---
## Type casting
### Numbers > `Number()`
```javascript
const nanInitial = "1.2whatever";
const converted = Number(initial);
console.log(typeof converted); // Number
console.log(converted); // NaN
```
---
## Type casting
### Numbers > `parseFloat()`
```javascript
const initial = "1.2";
const converted = Number(initial);
console.log(typeof converted); // Number
console.log(converted); // 1.2
```
---
## Type casting
### Numbers > `parseFloat()`
```javascript
const initial = "1.2whatever";
const converted = Number(initial);
console.log(typeof converted); // Number
console.log(converted); // 1.2
```
---
## Type casting
### Numbers > `parseInt()`
- `parseInt(<castedString>[, <radix>])`
- Casts to `number` _**and**_ only returns the integer part
- `<radix>`
- It does **NOT** always default to `10`
- $ r \in \mathbb{Z} : r \in [2, 32] $
---
## Type casting > Numbers
### `parseInt()` > Default radix
| Value | Default radix |
| ----------------- | ------------- |
| `"^[+-]?0[xX].+"` | 16 |
| Any other string | 10 |
---
## Type casting
### Numbers > Unexpected conversions
| Original value | Converted to number |
| -------------- | ------------------- |
| `""` | `0` |
| `[]` | `0` |
| `[<number>]` | `<number>` |
| `null` | `0` |
---
## Type casting
### String > Template literals
```javascript
const original = 1.23;
const converted = `${original}`;
console.log(typeof original); // "number"
console.log(typeof converted); // "string"
```
---
## Type casting
### String > `String()`
```javascript
const original = 1.23;
const converted = String(original);
console.log(typeof original); // "number"
console.log(typeof converted); // "string"
```
---
## Type casting
### String > `toString()`
| Original value | Converted to String |
| -------------- | --------------------------- |
| `1.1` | `"1.1"` |
| `true` | `"true"` |
| `[1, "str"]` | `"1,str"` (`arr.join(",")`) |
| Object | `[object Object]` |
| Function | Function body |
---
## Type casting
### Boolean > Double negation
```javascript
const original = "something";
const converted = !!original;
console.log(typeof original); // "string"
console.log(typeof converted); // "boolean"
```
---
## Type casting
### Boolean > `Boolean()`
```javascript
const original = "something";
const converted = Boolean(original);
console.log(typeof original); // "string"
console.log(typeof converted); // "boolean"
```
---
## Type casting
### Boolean > Unexpected conversions
| Original value | Converted to boolean |
| -------------- | -------------------- |
| `"0"` | `true` |
| `"00"` | `true` |
| `""` | `false` |
---
## Strict vs coersive equality
```javascript
console.log("12.3" === 12.3); // false
console.log("12.3" == 12.3); // true
console.log("12.3" !== 12.3); // true
console.log("12.3" != 12.3); // false
```
---
## Deep comparison
### Arrays
```javascript
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false
```
---
## Deep comparison
### Object
```javascript
const obj1 = { a: 1 };
const obj2 = { a: 1 };
console.log(obj1 === obj2); // false
```
---
## Deep comparison
### Other objects (Set, Date, etc.)
- Keep in mind that most of the utility types behave like objects
- Some utility types offer a unique representation using some instance method, e.g.: `<date>.getTime()`
---
## Closures
- A function + its surrounding lexical environment
- An inner function with access to the outer function scope even after the outer function was executed
---
## Scopes
```mermaid
flowchart TB
0(JS Scopes)--->1(Global)
2(Function)
3(Block*)
0--->2
0--->3
```
_(\*) Introduced in ES6 (2015)_
---
## Scopes
### Using `var` and assignment without declaration
```javascript
{
var global1 = "something 1";
global2 = "something 2";
let blockScoped = "something 3";
}
console.log(global1); // "something 1"
console.log(global2); // "something 2"
console.log(blockScoped); // ReferenceError
```
---
## Scopes
### Block scope > Typical scenario
```javascript
for (let i = 0; i < 10; i++) {
console.log(i); // i
}
console.log(window.i); // undefined
console.log(i); // ReferenceError
```
---
## Scopes
### Block scope > Typical scenario
```javascript
for (var i = 0; i < 10; i++) {
console.log(i); // i
}
console.log(window.i); // 10
console.log(i); // 10
```
---
## IIFEs
```javascript
(function () {
var someVar = 1;
console.log(window.someVar);
})();
```
---
## Hoisting
- Variable _declarations_ are hoisted
- Variable _initializations_ are _NOT_ hoisted
- `let` and `const` will throw an error if you try to use the variable before the declaration
- `var` won't throw but the value may be `undefined`
---
## Hoisting
- Functions are hoisted
- Classes are *NOT* hoisted (even though they're technically functions too)
---
## Method chaining
### Depending on the type
```javascript
const arr = [1, 2, "hi", 3, "John"];
arr
.filter((item) => typeof item === "string")
.join(" ")
.replace(/^./, (c) => c.toUpperCase());
```
---
## Method chaining
### Using `this`
```javascript
class MyClass {
constructor(str) {
this.str = str;
}
append1() {
this.str = `${this.str}1`;
return this;
}
append2() {
this.str = `${this.str}1`;
return this;
}
}
```
---
## Method chaining
### Using `this`
```javascript
const instance = new MyClass("0");
console.log(instance.str); // "0"
instance.method1().method2();
console.log(instance.str); // "012"
```
---
## Prototypal inheritance
- Objects have a special hidden property called _prototype_
- If JavaScript can't find a property in the object, it will try to find it in its prototype
---
## Prototypal inheritance
```javascript
function Animal(name) {
this.name = name;
}
Animal.prototype.breathe = function () {
console.log("breathing...");
};
```
---
## Prototypal inheritance
```javascript
function Dog(name) {
Animal.call(this, name);
}
Object.setPrototypeOf(Dog.prototype, Animal.prototype);
// Alternative:
// Dog.prototype = Animal.prototype;
```
---
## Prototypal inheritance
```javascript
const d = new Dog("Courage");
d.breathe();
console.log(d.name);
```
---
## Strict mode
- Declared using `"use strict";`
- Can be only declared:
- At the beginning of the global scope
- At the beginning of a function scope
---
## Strict mode
### Most important modifications
- You must declare variables before using them
- Functions aren't hoisted
- More details
- [Strict Mode on MDN](https://devdocs.io/javascript/strict_mode)
- [JS Strict Mode on W3Schools](https://www.w3schools.com/js/js_strict.asp)
---
## Wrapping up
- Topics covered
- Quirky topics
- Next session
- Coming up...
- Schedule
---
{"metaMigratedAt":"2023-06-17T16:15:46.875Z","metaMigratedFrom":"YAML","title":"Session 6: Quirky Topics","breaks":true,"contributors":"[{\"id\":\"7bc28690-699b-4cf5-8a18-7fc3fddcbd0c\",\"add\":7878,\"del\":0}]"}