# [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.

* 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