---
# System prepended metadata

title: JS Learning Notes
tags: [JavaScript]

---

# [JavaScript]

:::info
:bulb: Hello all, this is an informal learning space for JS. The learning materials come from codecademy, which is a great learning source, and I welcome everyone to pick up programming skills on it!
:::


## Data Type (Primitive data type)
* Number
* BigInt
* String
    * concatenation, e.g., 'word1'+"word2"
* Boolean
* Null
* Undefined
* Symbol
* Object

## Property
* The [prototype] is a property available with all JavaScript objects.
* The prototype property allows you to add new properties and methods to strings.


## Method : action we perform
* e.g., console.log (console is an object, .log() is a method)


## JS built-in objects
* e.g., Math.random()

## Interpolation
* e.g., console.log(`I own a pet ${myPet}.`);

## short-circuit evaluation
```javascript
let tool = 'marker'
let stationary = tool || "pen"
```
## function expression
* function declaration: ```function getScore()```
* function expression: ``` const totalScore = function(score, subject)```
* Arrow functions : ``` const totalScore = (score, subject)=>{}```
* concise arrow functions: ``` const totalScore = score => score*10```
* higher order function: function is first-class object

## Ternary operator
`isNightTime ? console.log('Turn on the lights!') `

## Array
each content item inside an array is `element`

## Advanced Objects
* arrow function defined in an object inherently binds an defined `this` value.
```javascript
const goat = {
  dietType: 'herbivore',
  makeSound() {
    console.log('baaa');
  },
  diet: () => {
    console.log(this.dietType);
  }
};

goat.diet(); // Prints undefined
```
 In the code snippet above, the value of this is the global object, or an object that exists in the global scope, which doesn’t have a `dietType` property and therefore returns `undefined`.



## Getters and Setters
:::success
* Getters are methods that get and return the internal properties of an object.
* Setter methods reassign values of existing properties within an object.
    
source: [Setters](https://www.codecademy.com/courses/introduction-to-javascript/lessons/advanced-objects/exercises/setters)
:::

* robot there is a getter method for numOfSensors but no setter method.
* Add a setter method named numOfSensors using the set keyword. Provide a parameter of num.

```javascript
const robot = {
  _model: '1E78V2',
  _energyLevel: 100,
  _numOfSensors: 15,
  get numOfSensors(){
    if(typeof this._numOfSensors === 'number'){
      return this._numOfSensors;
    } else {
      return 'Sensors are currently down.'
    }
  },
  set numOfSensors(num){
    if(typeof num === 'number' && num >=0){
      this._numOfSensors = num;
    }else {
      console.log('Pass in a number that is greater than or equal to 0');
    };
  }
  
};

robot.numOfSensors = 100; //Use the numOfSensors setter method on robot to assign _numOfSensors to 100.

console.log(robot.numOfSensors);
```
:star:  _energyLevel代表privacy。

place an underscore _ before the name of a property to mean that the property should not be altered.



## Factory Function
create many instances of an object quickly
此Function目的，就是用來大量製造object
```javascript
const monsterFactory = (name, age, energySource, catchPhrase) => {
  return { 
    name: name,
    age: age, 
    energySource: energySource,
    scare() {
      console.log(catchPhrase);
    } 
  }
};

const ghost = monsterFactory('Ghouly', 251, 'ectoplasm', 'BOO!');
ghost.scare(); // 'BOO!'
```




    
## Class & inheritance

```javascript
class Cat extends Animal {
  constructor(name, usesLitter) {
    super(name);
    this._usesLitter = usesLitter;
  }
}
```
* `extends` makes the methods of animal class available in the cat class
*  must always call the `super` method before you can use the this keyword

  
## Static Mehtods
* static methods are called directly from the class, but not from an instance of the class.
* If you call static methods by class instance, there will be `TypeError`

```javascript
class HospitalEmployee {
  constructor(name) {
    this._name = name;
    this._remainingVacationDays = 20;
  }
  
  get name() {
    return this._name;
  }
  
  get remainingVacationDays() {
    return this._remainingVacationDays;
  }
  
 // create a static method
  static generatePassword(){
    return Math.floor(Math.random()*10000)
  }

}

console.log(HospitalEmployee.generatePassword())
//generate a random number
```

## Promise
* automatically call `executor` function, then it starts an asynchronous operation.
* `executor` function usually refer to two parameters, `resolve()` and `reject()`
* .then: higher-order function— it takes two callback functions as arguments. We refer to these callbacks as handlers. When the promise settles, the appropriate handler will be invoked with that settled value.
* The success callback is sometimes called the “success handler function” or the onFulfilled function. The failure callback is sometimes called the “failure handler function” or the onRejected function. 

### Promise.all()
* To maximize efficiency we should use concurrency, multiple asynchronous operations happening together. With promises, we can do this with the function `Promise.all()`.


## Async await
* Javascript uses event-loop instead of stopping the execution while it waits.
* Three ways to write async actions
```javascript
const fs = require('fs');
const promisifiedReadfile = require('./promisifiedReadfile');
      
// Here we use fs.readfile() and callback functions:
fs.readFile('./file.txt', 'utf-8', (err, data) => {
  if (err) throw err;
  let firstSentence = data;
  fs.readFile('./file2.txt',  'utf-8', (err, data) => {
    if (err) throw err;
    let secondSentence = data;
    console.log(firstSentence, secondSentence);
  });
});

// Here we use native promises with our "promisified" version of readfile:
let firstSentence;
promisifiedReadfile('./file.txt', 'utf-8')
  .then((data) => {
    firstSentence = data;
    return promisifiedReadfile('./file2.txt', 'utf-8');
  })
  .then((data) => {
    let secondSentence = data;
    console.log(firstSentence, secondSentence)
  })
  .catch((err) => {console.log(err)});

// Here we use promisifiedReadfile() again but instead of using the native promise .then() syntax, we declare and invoke an async/await function:
async function readFiles() {
  let firstSentence = await promisifiedReadfile('./file.txt', 'utf-8');
  let secondSentence = await promisifiedReadfile('./file2.txt', 'utf-8');
  console.log(firstSentence, secondSentence);
}

readFiles();


```

### await
* The `await` keyword can only be used inside an `async` function. `await` is an operator: it returns the resolved value of a promise.
* `await` returns the resolved value of the awaited promise.

### try...catch
* use try...catch statements within our async functions for error handling.


## Request with fetch API
* JavaScript uses an event loop to handle asynchronous function calls. When a program is run, function calls are made and added to a stack. 

### Approach 1: fetch API with .then
* We can chain `.then()` methods to handle `promises` returned by the `fetch()` function.
```javascript
const apiKey = '60b2f9aa6133458a9e6b7871725e5bc9';
const url = 'https://api.rebrandly.com/v1/links';

// Some page elements
const inputField = document.querySelector('#input');
const shortenButton = document.querySelector('#shorten');
const responseField = document.querySelector('#responseField');

// Asynchronous functions
const shortenUrl = () => {
  const urlToShorten = inputField.value;
  const data = JSON.stringify({destination: urlToShorten});
  
fetch(url, {
    method: 'POST',
    headers: {
      'Content-type': 'application/json',
      'apikey': apiKey
    },
    body: data
  })
  .then(response=> {
    if(response.ok){
      return response.json()
    }
    throw new Error('Request failed!')
  },(networkError => {
    console.log(networkError.message)
  }))
  .then((jsonResponse)=> {
    renderResponse(jsonResponse)
  })
}
```


### Approach 2: fetch API with await

```javascript
const apiKey = 'your-API-key';
const url = "https://api.rebrandly.com/v1/links";

// Some page elements
const inputField = document.querySelector("#input");
const shortenButton = document.querySelector("#shorten");
const responseField = document.querySelector("#responseField");

// Asynchronous functions
const shortenUrl = async () => {
  const urlToShorten = inputField.value;
  const data = JSON.stringify({ destination: urlToShorten });
  try {
    const response = await fetch(url, {
      method: "POST",
      body: data,
      headers: {
        "Content-type": "application/json",
        apikey: apiKey,
      },
    });
    if (response.ok) {
      const jsonResponse = await response.json();
      renderResponse(jsonResponse);
    }
  } catch (error) {
    console.log(error);
  }
};
```

## Error

* to create a customized error, you can write  `new Error('a customized message')`

### throw
* When we use the `throw` keyword, the error is thrown and code after the throw statement will not execute. 
* example : `throw Error('message')`


## Currying JS
* 

## hoisting in JS
* JavaScript hoists function declarations, including the function body, to the top of its scope
* var variables are hoisted to the top of function blocks.
* Since the release of ES6, there are really no situations where it is preferable to use var variables.
* let and const differ from var in how they initialize as well; while the names are hoisted, they are not initialized.
* [MDN Hoisting in JS]


## event loop
* Since JavaScript is single-threaded, as we saw in the for loop example, we’ll never have that flavor of “true” concurrency.
* The event loop is made up of these parts:
    * Memory Heap
        * a block of memory where we store objects in an unordered manner. JavaScript variables and objects that are currently in use are stored in the heap    
        * The heap provides dynamic memory allocation at runtime for data types that don’t have a fixed size, like objects and functions. 
        * Objects are stored in heap while the fixed-size reference is stored in the call stack, so when you modify a value, you are changing the reference.
    * Call Stack
        * The stack, or call stack, tracks what function is currently being run in your code.
        * Frames enter the stack in a last in, first out (LIFO) order.
        ![image](https://hackmd.io/_uploads/HyLMrMdVp.png)

    * Event Queue
        *  a list of messages corresponding to functions that are waiting to be processed, such as various web APIs or async functions.
        *  event queue in context: When the call stack is empty, if there is anything in the event queue, the event loop can add those one at a time to the stack for execution.
    * Event Loop
    * Node or Web APIs

### Memory leaks

## Design pattern
* [singleton patter- by WDS]

[prototype]:https://www.w3schools.com/jsref/jsref_prototype_string.asp
[MDN Hoisting in JS]: https://developer.mozilla.org/en-US/docs/Glossary/Hoisting
[singleton patter- by WDS]: https://www.youtube.com/watch?v=sJ-c3BA-Ypo   


