# JS Learning
- https://www.youtube.com/watch?v=8aGhZQkoFbQ&t=1s
- https://ithelp.ithome.com.tw/users/20065504/ironman/1259
## String Process
```javascript=mixed
.subString(start_index, end_index);
```
## Destructure
```javascript=
const person = {
firstName: 'Allen',
lastName: 'Wang',
age: 19,
address: {
street: '66 main st',
city: 'Keelung'
}
}
// add property
person.school = {
highSchool: 'CKHS'
};
console.log(person);
// destructure
const {firstName, lastName, school:{ highSchool }} = person;
console.log(firstName, lastName, 'is from', highSchool);
```
## JSON
> the main difference is that the property and the string content both are doublequoted
Ex:
```javascript=
const todos = [
{
id: 1,
text: 'Garbage',
isCompleted: true
},
{
id: 2,
text: 'Meeting',
isCompleted: true
},
{
id: 3,
text: 'Homework',
isCompleted: false
},
]
console.log(todos);
// convert it to JSON form
const todosJSON = JSON.stringify(todos);
console.log(todosJSON);
```
## For Loop
```javascript=
for (let i = 0; i < 4; i++) {
console.log(`The recent index is ${i}`);
}
// While
let i = 0;
while (i < 4) {
console.log(`While loop ${i++}`);
}
```
## `forEach map filter`
```javascript=
const todos = [
{
id: 1,
text: 'Garbage',
isCompleted: true
},
{
id: 2,
text: 'Meeting',
isCompleted: true
},
{
id: 3,
text: 'Homework',
isCompleted: false
},
]
// Basic For Loop
for (let i = 0; i < todos.length; i++) {
console.log(todos[i].text);
}
// Advanced one
for (let todo of todos) {
console.log(todo.text);
}
// forEach
todos.forEach(function(todo){
console.log(todo.text);
})
// map: returns a new array
const todosText = todos.map((todo) => todo.text)
console.log(todosText);
// filter: returns a filtered array
const todosCompleted = todos.filter((todo) => todo.isCompleted === true)
console.log(todosCompleted);
// Mixed each of these together!
const todosMixed = todos.filter((todo) => {
return todo.isCompleted === true;
}).map((todo) => {
return todo.text;
})
console.log(todosMixed);
```
## Some, Every
```javascript=
const students = [
{
name: "Daniel",
age: 21,
country: "Malaysia",
},
{
name: "Noob",
age: 20,
country: "Taiwan",
},
{
name: "Coin",
age: 21,
country: "Taiwan",
},
];
const found_age = students.every((x) => x.age === 21);
// result is false
console.log(`All of the students is 21 years old: ${found_age}`);
const found_name = students.some((x) => x.name === "Noob");
console.log(`Some of the students are called "Noob": ${found_name}`);
```
## [For of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
```javascript=
const iterable = new Map([['a', 1], ['b', 2], ['c', 3]]);
for (const entry of iterable) {
console.log(entry);
}
// ['a', 1]
// ['b', 2]
// ['c', 3]
for (const [key, value] of iterable) {
console.log(value);
}
// 1
// 2
// 3
```
### Difference between `for` of and `forEach` (the position of index)
```javascript=
for(let [index, value] of array) {...}
sth.forEach(value, index) => {...}
```
## Conditional Statement
> `(statement) (condition) ? (true) : (false)`
```javascript=
const x = 5;
const xIsFive = x === 5 ? true: false;
console.log(xIsFive);
```
## Swtich Statement
```javascript=
const color = 'red'
switch(color) {
case 'blue':
console.log(`color is blue`);
break;
case 'red':
console.log(`color is ${ color }`);
break;
default:
console.log(`color is nether blue or red`);
break;
}
```
## Function
```javascript=
// num1 = 1, num2 = 2 are default values
function addNum(num1 = 1, num2 = 2) {
return num1 + num2;
}
```
## Arrow Function
```javascript=
// arrow function
const addNum = (num1, num2) => {
return num1 + num2;
}
// in case of return, it can be shortened like following
const addNum = (num1, num2) => num1 + num2;
console.log(addNum(2,2));
```
## Object Oriented
```javascript=
function Person(firstName, lastName, dob) {
this.firstName = firstName;
this.lastName = lastName;
this.dob = new Date(dob);
}
Person.prototype.getBirthYear = function() {
return this.dob;
}
Person.prototype.getFullName = function() {
return `${ this.firstName} ${ this.lastName }`
};
// ES6
class Person {
constructor (firstName, lastName, dob) {
this.firstName = firstName;
this.lastName = lastName;
this.dob = new Date(dob);
}
getBirthYear() {
return this.dob.getFullYear();
}
getFullName() {
return `${this.firstName} ${this.lastName}`;
}
}
// Instantiate Object
const person1 = new Person('Allen', 'Wang', '3-4-2002');
console.log(person1.getBirthYear());
```
## extends, super
```javascript=
class Person {
constructor (_name, _age) {
this.name = _name;
this.age = _age;
}
describe() {
console.log(`my name is ${this.name}, and I'm ${this.age} years old`);
}
}
class Programmer extends Person {
constructor (_age, _name, _hobby) {
super(_age, _name);
/* super take place of the following:
constructor (_name, _age) {
this.name = _name;
this.age = _age;
}
*/
// Custom behavior
this.hobby = _hobby;
}
showHobby() {
console.log(`my name is ${this.name} and my hobby is ${this.hobby}`);
}
}
const person1 = new Person('Allen', 19);
const programmer1 = new Programmer('Alan', 15, 'eating');
person1.describe();
programmer1.describe();
programmer1.showHobby();
```
## Callback
```javascript=
const post = [
{
title: "Post One",
body: "This is post one",
},
{
title: "Post Two",
body: "This is post two",
},
];
function getPosts() {
setTimeout(() => {
let output = "";
post.forEach((value, index) => {
output += `<li>${value.title}</li>`;
});
document.body.innerHTML = output;
}, 1000);
}
// doesn't necessary to be named callback
function createPost(newPost, callback) {
setTimeout(() => {
post.push(newPost);
// wait for .push() before fires the callback()
callback();
}, 2000);
}
getPosts();
createPost({ title: "Post three", body: "This is post three" }, getPosts);
setTimeout(() => console.log(post), 2000);
```
## Promise
```javascript=
// εδΈεζ£
function createPost(newPost) {
return new Promise((resolve, reject) => {
setTimeout(() => {
const error = false;
if (!error) {
post.push(newPost);
resolve();
} else {
reject();
}
}, 2000);
});
}
getPosts();
createPost({
title: "Post three",
body: "This is post three",
}).then(getPosts);
```
## `Promise.all` `fetch()`
### Remark: `fetch()` has **two** .then()
```javascript=
// Promise.all
// 2 ways to write
// Promise.resolve('text') is always resolved
const promise1 = new Promise((resolve, reject) => resolve("Awesome"));
const promise1 = Promise.resolve("Awesome");
const promise1 = Promise.reject("Awesome");
const promise2 = 10;
// 2 ways to write
const promise3 = new Promise((resolve, reject) =>
setTimeout(reject, 1000, "Goodbye")
);
const promise3 = new Promise((resolve, reject) =>
setTimeout(resolve, 1000, "Goodbye")
);
const promise3 = new Promise((resolve, reject) => {
setTimeout(resolve("Goodbye"), 1000);
});
const promise4 = fetch("https://jsonplaceholder.typicode.com/todos/1").then(
(res) => res.json()
);
// if all resolved, .then(),
// if any of them is not resolved, .catch() will only catch the first one that rejects
Promise.all([promise1, promise2, promise3, promise4])
.then((values) => console.log(values))
.catch((msg) => console.log("error:", msg));
// return the first Promise to finish
Promise.race([promise1, promise2, promise3, promise4]).then((value) =>
console.log(value)
);
```
## Async / Await
```javascript=
// Async / Await
async function fetchData() {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await res.json();
console.log(data);
}
fetchData();
```
## Questions encountered
> Q: How to access to the first props of an object?
```javascript=
const obj = {
first: "1",
second: "2"
};
const firstValue = Object.values(obj)[0];
console.log(firstValue); // 1
```
## Eslint
- [eslint setup](https://medium.com/medvine/install-eslint-global-with-airbnb-style-guide-and-use-it-in-vscode-d752dfa40b21)
- [eslint setup-2](https://larrylu.blog/improve-code-quality-using-eslint-742cf1f384f1)
- [use eslint instead of pretter](https://daveceddia.com/vscode-use-eslintrc/)