Reading JavaScript guide on MDN (study notes)
Tags: javascript, codenewbie, webdev, programming
Published: 2021-08-29 22:23:10

I'm relearning JS by reading MDN's JS guide.

I’m doing so as a try to understand the weird stuff in JS cause there must be an explanation right?

This is more like personal notes but maybe it would be helpful to anyone else:) 

<aside>
💡 This may *or may not* be updated everyday

</aside>

## Grammar and types

- There's a third type of comments "Hashbang" comments
    
    ```jsx
    #!/usr/bin/env node
    ```
    
    it specifies the path to a specific JavaScript interpreter that you want to use to execute the script
    
    It acts the same as single-line comments `//` but 
    
    it must be at the beginning of a file
    
    it can't have any whitespace before
    
- you can use letters like å, ü (I mean they never said you can't but still I was like Woah when it run without errors)
    
    it's because JS uses the Unicode character set
    
- `let` vars are hoisted but not initialized unlike `var`
    
    they are considered to be in a *"temporal dead zone"*
    
    ```jsx
    console.log('The value of b is ' + b); // The value of b is undefined
    var b;
    
    console.log('The value of y is ' + y); // Uncaught ReferenceError: y is not defined
    let y;
    ```
    
- The `undefined` value converts to `NaN` when used in numeric contexts
- null value behaves as 0 in numeric contexts and as false in boolean contexts
- function expression is not hoisted
    
    ```jsx
    baz(); // TypeError: baz is not a function
    console.log(baz) // undefined
    var baz = function() {
      console.log('bar2');
    };
    ```
    
- Only with the + operator JavaScript converts numeric values to strings
    
    In case of + and the expression involving strings both sides are converted to string and concatenation is performed
    
    in case of any other operation it tries to convert both sides to numbers if it's okay then the operation is performed if not `NaN` is returned
    
    ```jsx
    x = 'The answer is ' + 42 // "The answer is 42"
    x = 'The answer is ' - 42 // NaN
    x = '45' - '3'  // 42
    x = '45' + '3' // 453
    ```
    
- you can create functions and dynamic named properties inside objects
    
    ```jsx
    var obj = {
        toString() {
         // Super calls
         return 'd ' + super.toString();
        },
        // Computed (dynamic) property names
        [ 'prop_' + (() => 42)() ]: 42
    };
    ```
    

---

## Loops and iteration

- Starting from es6 JS has block scope (for, if, while)
- JS labels used with `break` and `continue` to take effect on any block in the hierarchy
    
    for example if you have a loop and another inside of it you can use the label to break from the loop inside the the second loop
    
    ```jsx
    for (let i = 0; i < 5; i++) {
      console.log("i", i);
      for (let j = 5; j > 0; j--) {
        if (i === j) break; // breaks only from the second for and continues the loop
      }
    }
    
    loop1: for (let i = 0; i < 5; i++) {
      console.log("i", i);
      for (let j = 5; j > 0; j--) {
        if (i === j) break loop1; // breaks from both loops
      }
    }
    ```
    
- Can you use labeled statement to break from `forEach` loops? No by experiment!
- for ... of → iterate over iterable objects values (Map, Set, Array)
- for ... in → iterate over enumerable property keys of an object

---

## Fun Fun Functions

- function hoisting only works with function declarations not with function expression or arrow function
- A function can call itself using `arguments.callee()` nice to know but don't use it
- When you have a function with an inner function that inner function forms closure which means it can access all the variables defined in the outer function
    
    The inner function has a reference to the args in the outer function and the reference is preserved until the inner function is no longer accessible 
    
- The `arguments` object it's an array-like not an array it only has `length` property and numbered index
- an arrow function doesn't have its own `this`, `super`, or `arguments`
- use `Number.isNaN()` instead of `isNaN` cause `isNaN` is weird and you know it
- the only difference between `encodeURI` and `encodeURIComponent` is
    
    `encodeURI` ignores protocol and domain name
    
    `encodeURIComponent` encodes everything the whole string
    

---

## Expressions and operators

- + true returns 1
- >> shifts bits to the right
- >>> shifts bits to the right and adds zeros at the left  instead of the shifted bits
- In bitwise operations the operands are converted to 32bits binary representation
- && and || returns one of the expression values
- Use nullish operator ?? Instead of || in case of 0 and ‘’ are valid values
- `typeof null    // returns object!!!!!!`
- `void` operator evaluates an expression then returns undefined
    
    It can be used with functions that don't intend to return any values
    
    ```jsx
    function x() {
      const x = 2;
      console.log("X", x);
      return x;
    }
    
    const revealed = () => x();
    console.log(revealed()); // 2
    
    const hidden = () => void x();
    console.log(hidden()); // undefined
    ```
    
- In operator: it’s like `hasOwnProperty` in objects

---

## Numbers & Dates

- Use BigInt to represent very large numbers
- Math can’t be used with BigInt values
- you can't mix and match BigInt and Number values in the same operation
- Number like 0777 (with leading 0 and numbers are less than 8)would be considered an octal in non strict mode
- To write an octal number in ES5 add the prefix 0o777
- Math.toPrecision ??
- Creating Date without the new keyword returns only a date string not an object
- Date.parse() to convert a date string to date object

## Text formatting

- When using a string literal `let str = “str”`
    
    JS converts it to a temporary String object apply any methods then returns the result discarding  the object
    
- Strings are immutable array-like object so you can't just assign a value to a certain index
    
    ```jsx
    let str = “str”;
    str[2] = “y”; // won't do anything 
    ```
    
- str.repeat(42) just repeats a string
- charCodeStr.normalize() cause a string can be represented in different ways using char code normalize makes all the presentations are equal
- Intl.collator(sort type) used for sorting and comparing strings for internationalization like handling different sort types in German

## Regular Expressions

- Use literal regular expression if the pattern is a constant for better performance

## Indexed collections

- Looping through a list of nodes? use this it’s more convenient
    
    You wont need to check the length 
    
    You make sure the node is assigned to the var
    
    ```jsx
    let divs = document.getElementsByTagName('div')
    for (let i = 0, div; div = divs[i]; i++) {
      /* Process div in some way */
    }
    ```
    
- it is not advisable to iterate through JavaScript arrays using for...in loops, because normal elements and all enumerable properties will be listed.
- How to call array methods on array-like objects
    
    Using prototype.call
    
    ```jsx
    function printArguments() {
      Array.prototype.forEach.call(arguments, function(item) {
        console.log(item);
      });
    }
    ```
    
- Typed arrays are array-like objects with a mechanism for accessing raw binary data
- Typed arrays architecture is divided into buffer and view
    
    Buffer is a chunk of data that has no mechanism to access like an ArrayBuffer
    
    View is your way to access the buffer data it provides a context with data type (that is why it’s typed array it has a type!), starting offset and number of elements like a DataView
    
- There are different typed array views and they have descriptive names like `int8Arrays` which means the view size is 8 bits/1byte
- There is one special typed array view, `Uint8ClampedArray`, which clamps the values between 0 and 255. This is useful for Canvas data processing

## Keyed Collections

- Normal objects are not iterable
- You can get the size of a Map easily, while you have to manually keep track of size for an Object
- The iteration of maps is in insertion order of the elements. The order doesn’t matter in objects
- Use maps if there is a need to store primitive values as keys because object treats each key as a string whether it's a number value, boolean value or any other primitive value
- WeakMap keys are only objects and they are weakly held meaning that they are a target of garbage collection (GC) if there is no other reference to the object anymore
- WeakMap keys are not enumerable you can’t have access to the list of keys
- WeakMaps are usually used for privacy [check an example](https://fitzgeraldnick.com/weblog/53/)
- You can convert from set to array using spreed operator
- WeakSets are collections of objects only
- WeakSets are not enumerable

## Working with objects **(to reread)**

- Object.create() method. This method can be very useful, because it allows you to choose the prototype object for the object you want to create without having to define a constructor function. >> inheritance
- You access forms in a document using document.forms
    
    document.forms[1] // returns first document appears in the document 
    
    document.forms[‘my-form’] // returns the form with name property equals my-form
    
- Getters and setters can be added to an object at any time after creation using the Object.defineProperties method
    
    ```jsx
    var o = { a: 0 };
    
    Object.defineProperties(o, {
        'b': { get: function() { return this.a + 1; } },
        'c': { set: function(x) { this.a = x / 2; } }
    });
    
    o.c = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
    console.log(o.b); // Runs the getter, which yields a + 1 or 6
    ```
    

## Details of the object model **(to reread)**

- Creating a new object from a function you can omit the parenthesis if there're no params
    
    ```jsx
    const jane = new Engineer;
    ```
    
- Method delegation can preserve memory resources because you only need one copy of each method to be shared by all instances
    
    ```jsx
    function Greeter(name) {
      this.name = name || "John Doe";
    }
    
    Greeter.prototype.hello = function hello() {
      return "Hello, my name is " + this.name;
    };
    
    const george = new Greeter("George");
    const jack = new Greeter("jack");
    
    console.log(george.hello === jack.hello); // true (means they have the same reference)
    ```
    
- In JavaScript, any function can create new objects. When it’s not a constructor function, it’s called a factory function like `Object.create()`

## Using Promises

- a promise is a returned object to which you attach callbacks, instead of passing callbacks into a function.
- It's possible to chain *after* a failure, i.e. a `catch`, which is useful to accomplish new actions even after an action failed in the chain Like a finally in a try catch
- Promises rejection events are of type `[PromiseRejectionEvent](https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent)` has as members a `[promise](https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent/promise)` property indicating the promise that was rejected, and a `[reason](https://developer.mozilla.org/en-US/docs/Web/API/PromiseRejectionEvent/reason)` property that provides the reason given for the promise to be rejected
- All rejections are raised to global scope (either window or worker) And they come in two types
    - **`rejectionhandled`** Sent when a promise is rejected, after that rejection has been handled by the executor's `reject` function.
    - **`unhandledrejection`**Sent when a promise is rejected but there is no rejection handler available.
- Promisifying `setTimeout`
    
    ```jsx
    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    
    wait(10*1000).then(() => saySomething("10 seconds")).catch(failureCallback);
    ```
    
- You can use `Promise.resolve()` and `Promise.reject()`to manually create an already resolved or rejected promise
- Promise.all reusable compose function
    
    ```jsx
    const applyAsync = (acc,val) => acc.then(val);
    const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));
    ```
    
- 

[Next Read](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#relational_operators)