nomad coder의 javascript ES6 이상 버전의 문법에 대한 강의를 들으면서 정리해둔 내용이다.
ES6 이후의 새로운 문법들이 총 정리 되어있는 포스팅이 없는 것 같아서 열심히 정리해 두었다.
(노마드코더 와이프분인 lynn님에게 이메일 보내서 내 블로그에 게시해도 좋다는 회신을 받았음)
ES6이상 새로운 의 모~~~든 문법을 포함하는 내용이 아닐 수도 있지만, 대부분 포함되어 있을것임.
------------------------------------------------------------------------------------------------------------------------
아직 마지막 class부터 그 뒷부분 내용이 쪼~금 덜 정리되었는데 금방 업로드 예정임!
9. Rest and Spread
1. Introduction to Spread
=> spread부터 보자면, spread는 어떤 자료구조 내부의 데이터를 풀어헤쳐놓는거임.
const friends = [1, 2, 3, 4];
console.log(friends); // [1, 2, 3, 4] <- 배열 자체
console.log(…friends); // 1 2 3 4 <- 배열 안의 값들이 나오게 됨
다시 예를 들면,
const friends = [1, 2, 3, 4];
const family = [“a”, “b”, “c”, “d”];
console.log([…friends, …family]); <- 모든 요소들을 담고 있는 하나의 array를 얻을 수 있다
object에도 이러한 spread를 사용 할 수 있다.
const sexy = {
name: “nico”,
age: 24
};
const hello = {
sexy: true,
hello: “hello”
};
console.log({…sexy, …hello});
2. spread application (스프레드 적용)
=> 기존의 데이터 내용을 새로운 변수에 할당하고 싶을때 사용한다
const friends = [“nico”, “lynn”];
const newFriends = […friends, “dal”];
console.log(newFriends);
----------------------------------------
const first = [“mon”, “tue”, “wed”];
const weekend = [“sat”, “sun”];
const fullWeek = […first, “thu”, “fri”, …weekend];
console.log(fullWeek);
----------------------------------------
Object에도 아래와 같이 적용시킬 수 있다.
const nico = {
username: “nico”
};
console.log({…nico, password: 123});
----------------------------------------
const lastName = prompt(“Last Name”); // lastName을 입력받는다
const user = {
username: “nico”,
age: 24,
lastName: lastName !== “” ? lastName : undefined
};
lastName을 입력받지 못한 경우, user객체에 아예 lastName요소가 없도록 하고싶으면 아래와 같이 하면 됨.
const lastName = prompt(“Last Name”); // lastName을 입력받는다
const user = {
username: “nico”,
age: 24,
…(lastName !== “” && { lastName })
};
console.log(user);
3. Intro to Rest Parameters
=> rest란 모든 값들을 하나의 변수로 축소시키는 것을 의미한다.
=> rest문법은 array를 생성한다.
const infiniteArgs = (…kimchii) => console.log(kimchi);
infiniteArgs(“1”, 2, true, “laalla”, 1, 4, 5)
----------------------------------------
const bestFriendMaker = (firstOne, …rest) => {
console.log(`My best friend is ${firstOne}`;
console.log(rest);
}
bestFriendMaker(“nico”, “lynn”, “dall”, “japan guy”);
4. Rest + Spread + Destructure Magic
=> rest문법은 특정 속성값을 제외시킬 수 있다.
const user = {
name: “nico”,
age: 24,
password: 12345
}
user[“password”] = null;
console.log(user);
지금까지는 위와 같이 코딩을 했음.
이렇게 하면 여전히 password라는 요소는 남아있게 된다.
----------------------------------------
아래와 같이 rest문법을 사용하면 멋지게 처리가능.
const user = {
name: “nico”,
age: 24,
password: 12345
}
const killPassword = ({ password, …rest}) => rest;
const cleanUser = killPassword(user);
console.log(cleanUser);
----------------------------------------
아래와 같이 defualt값의 설정과 함께 새로운 요소를 추가할 수도 있다.
const user = {
name: “nico”,
age: 24,
password: 12345
};
const setCountry = ({country = “KR”, …rest }) => ({country, …rest});
console.log(setCountry(user));
----------------------------------------
객체의 키값을 변경해줄 수도 있음.
const user = {
NAME: “nico”,
age: 24,
password: 12345
};
const rename = ({NAME:name, …rest}) => ({name, …rest});
console.log(rename(user));
10. For Of Loop
루프는 기본적으로 같은 일을 반복하는 것임.
const friends = [“Nico”, “Lynn”, “ha”, “hu”];
for(let i = 0; i <friends.length; i++){
console.log(friends[i]);
}
----------------------------------------
const friends = [“Nico”, “Lynn”, “ha”, “hu”];
const addHeart = (c, i, a) => console.log(c, i, a);
// forEach는 두번째 인자로 index를 받고, 세번째 인자로는 current array를 받는다
friends.forEach(addHeart)
기존의 방식은 위와 같이 하는 것이었는데, 별로 섹시하지 않다. for of를 써보자.
for(const friend of friends){
console.log(friend);
};
mdn에서 보면 알겠지만, for~of는 iterable한 모든 것에 대해 사용 가능하다.NodeList, Stirng 등등..
그리고 for~of는 어떤 요소를 찾는순간 어떤 연산을 수행하도록 만들 수 있다.
어떤 조건문을 내부에 적어줌으로써 중간에 Loop를 멈추도록 할 수도 있음.
const friends = [“Nico”, “Lynn”, “Japan Guy”, “Autumn”, “Dal”, “Mark”, “Pipe”, “Theo”];
for(const friend of friends){
if(friend === “Dal”){
break;
}
console.log(friend);
};
이렇게 for~of문법을 상요하면 데이터베이스에 어떤 데이터들을 보내다가 데이터베이스에 공간이 모자란다면,
데이터 보내는 것을 중단하도록 할 수도 있다.(에러가 나지 않도록 함)
11. Promises
1. Creating Promises
=> Promise의 핵심은 내가 아직 할당받지 못한 value(아직 모르는 값)과 함께 작업 할 수 있다는 것이다.
const amIsexy = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, “Yes you are!”); // setTimeout에는 handler와 그에 넘겨줄 인자를 두번재, 세번째 파라미터로 적어서 각각 넘겨줄 수 있다.
});
console.log(amIsexy);
setInterval(console.log, 1000, amIsexy);
// 3초간 <pending>상태로 console이 찍히다가 3초 이후에는 <resolved>가 나오는 것을 확인 할 수 있다.
2. Using Promises
=> then을 이용해서 promise가 resolve를 통해 리턴하는 것을 받아서 처리할 수 있다.
=> 콘솔에 빨간색 글자로 error 메시지를 띄우고 싶다면 Promise에서 reject를 사용한다.
const amIsexy = new Promise((resolve, reject) => {
resolve(“Yes, you are!”);
});
const thenFn = value => console.log(value);
amIsexy.then(thenFn);
----------------------------------------
const amIsexy = new Promise((resolve, reject) => {
reject(“no, you are not!”);
});
amIsexy.then(value => console.log(value););
// 이렇게 하면 콘솔에 빨간색 글자로 uncaught error라고 뜬다. 아무도 잡지 못한 에러라는 거임.
// catch는 이러한 빨간색 글자로 나타나는 에러를 잡아서 처리하기 위해 사용됨.
amIsexy
.then(result => console.log(result);)
.catch(error => console.log(error););
// 이렇게 하면 “no, you are not!”이 빨간 글자로 안뜨고 정상적으로 출력이 됨.
// 즉 then은 Promise 문법에서 리턴되는 resolve를 처리하고, catech는 reject를 처리한다.
// 따라서 then과 catch를 사용할 때는 Promise의 문법 구성을 확인해야 한다
// then과 catch는 순서대로 실행되는 것이 아니다. then 하나는 여러개 사용 될 때 순서대로 실행됨.
// then이 실행되면 catch가 실행되지 않고, catch가 실행되면 then이 실행되지 않음.
3. Chaining Promises
=> then 내부에서 resolve로 받은 값을 처리하고, 그 결과를 다시 그 다음 then으로 넘겨줄 수 있다.
const amIsexy = new Promise((resolve, reject) => {
resolve(2);
});
amIsexy
.then(number =>{
console.log(number*2);
return number*2;
})
.then(otherNumber =>{
console.log(otherNumber*2);
})
----------------------------------------
const amIsexy = new Promise((resolve, reject) => {
resolve(2);
});
const timesTwo = number => number*2;
amIsexy
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(lastNumber => console.log(lastNumber););
만약에 중간에 에러가 난다면?
amIsexy
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(() => {
throw Error(“Something is wrong”);
})
.then(lastNumber => console.log(lastNumber););
// catch구문을 사용해서 에러문을 처리해 주지 않으면 빨간색 글자로 에러가 난다
amIsexy
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(timesTwo)
.then(() => {
throw Error(“Something is wrong”);
})
.then(lastNumber => console.log(lastNumber););
.catch(error => console.log(error));
// 만약 위에서, promise구문 안에서 2를 리턴하는 것이 resolve가 아니라 reject였다면, catch로 바로 넘어가서 2가 콘솔로그로 출력 될 것임.
4. Promise.all
=> promise chaining을 사용하는 대신 promise.all을 사용할 수 있다.
const p1 = new Promise(resolve => {
setTimeout(resolve, 5000, “First”);
});
const p2 = new Promise(resolve => {
setTimeout(resolve, 1000, “Second”);
});
const p3 = new Promise(resolve => {
setTimeout(resolve, 3000, “Third”);
});
const motherPromise = Promise.all([p1, p2, p3]);
// 시간설정에 관계없이 promise.all이 순서대로 값을 배열에 담는다 -> 모든 처리가 끝나야 결과를 출력함
motherPromise.then(values => console.log(values));
이때, promise.all이 받아야 하는 결과중 하나라도 reject가 일어나고 catch로 처리가 안된다면, 에러가 난다.
Promise.all에 catch처리를 하면, 처리해야할 promise 객체 중에 하나라도 reject가 일어나면
그 reject로 처리한 내용 하나만 catch를 통해 출력된다.
const p1 = new Promise(resolve => {
setTimeout(resolve, 5000, “First”);
});
const p2 = new Promise(resolve, reject => {
setTimeout(reject, 1000, “Second is rejected”);
});
const p3 = new Promise(resolve => {
setTimeout(resolve, 3000, “Third”);
});
const motherPromise = Promise.all([p1, p2, p3]);
motherPromise
.then(result => console.log(result))
.catch(err => console.log(err));
5. Promise.race
=> Promise.all이랑 사용법은 같음. 근데 race는 처리해야할 promise객체 중에 하나라도 처리되면 그게 리턴된다.
즉, 가장 빨리 처리되는 것이 결과를 정한다.
나열 순서가 아니라, 처리 속도 순서대로 결과를 도출하고 싶을때 사용한다.
const p1 = new Promise(resolve => {
setTimeout(resolve, 5000, “First”);
});
const p2 = new Promise(resolve, reject => {
setTimeout(reject, 4000, “Second is rejected”);
});
const p3 = new Promise(resolve => {
setTimeout(resolve, 3000, “Third”);
});
const motherPromise = Promise.race([p1, p2, p3]);
motherPromise
.then(result => console.log(result))
.catch(err => console.log(err)); // “Third”
----------------------------------------
Promise.race([p1, p2, p3])
.then(result => console.log(result))
.catch(err => console.log(err)); // “Third”
위 구문을 그냥 바로 이렇게 써도 된다.
6. .finally
=> 최종적으로 then이 호출되건, catch가 호출되건 그 이후에 마지막으로 호출되는 것이 finally임.
const p1 = new Promise((resolve, reject) => {
setTimeout(reject, 5000, “First”);
})
.then(value => console.log(value))
.catch(e => console.log(`${e} 에러남`))
.finally(() => console.log(“I’m done”));
7. Real world Promises
=> fetch는 Promise를 리턴한다.
fetch(“https://yts.am/api/v2/list_movies.json”)
.then(response => {
console.log(response);
return response.json(); // 여기서 리턴되는 것도 promise 객체임. 따라서 또 then으로 받아줘야함.
})
// response는 응답 객체 전체인데, .json()을 사용하면 거기서 body부분을 가져온다.(현재 body의 데이터 타입이 json이기 떄문임)
.then(json => console.log(json))
.catch(error => console..log(`This is error${e}`));
12. Async / Await
1. Aysnc Await
=> async/await은 기본적으로 Promise를 사용하는 코드를 더 보기좋게 만드는 문법이다.
사실 then, then,catch 이렇게 사용하는 방식은 좀 구식임.
=> 즉 async/await은 많은 then과 catch를 사용하지 않고 promise 밖에서 그 값을 가져오는 방법이다.
=> Promise를 끝내기 위해 수많은 then들을 사용하는 대신 await를 사용하면 된다.
=> await은 항상 async function 안에서만 사용 할 수 있다.
=> await는 기본적으로 Promise의 비동기작업이 끝나기를 기다린다.(resolve 혹은 reject가 끝나길 기다림)
=> Promise의 결과가 reject라서 에러가 나온다면, async함수 내부에 try catch문을 사용해서 이 에러를 처리해준다.
Promise와 Async를 한번 비교해 보자.
const getMoviesPromise = () => {
fetch(“https://yts.am/api/v2/list_movies.json”)
.then(response => {
console.log(response);
return response.json();
})
.then(json => console.log(json))
.catch(error => console..log(`This is error${e}`));
};
const getMoviesAsync = async () => {
const response = await fetch(“https://yts.am/api/v2/list_movies.json”); //마치 then을 사용한 것과 같은 첫번째 리턴값이 담긴다
const json = await response.json();
}
getMoviesAsync();
2. try catch / finally
const getMoviesAsync = async () => {
try {
const response = await fetch(“https://yts.am/api/v2/list_movies.json”);
const json = await response.json();
throw Error(“I’m hungry”); // await에 의해 발생한 에러 뿐만 아니라, 이 에러도 catch문에 의해 잡힌다.
} catch (err) {
console.log(err); // try에서 발생한 모든 에러가 여기로 출력됨
} finally {
console.log(“we are done”);
}
}
getMoviesAsync();
3. Parallel Async Await
=> promise.all 의 결과인 배열을 destructing으로 처리해서 할당시켜보자
const getMoviesAsync = async () => {
try {
const [moviesResponse, suggestionsResponse] = await Promise.all([
fetch(“https://yts.am/api/v2/list_movies.json”),
fetch(“https://yts.am/api/v2/movie_suggestions.json?movie_id=100”)
]);
const [movies, suggestions] = await Promise.all([
moviesResponse.json();
suggestionsResponse.json();
]);
console.log(movies, suggestions);
} catch (err) {
console.log(err);
} finally {
console.log(“we are done”);
}
}
getMoviesAsync();
13. Classes
1. Introduction to Classes
=> 이후 생성될 Object에 대한 blueprint 역할을 한다. 설계도 역할만 하므로, class만으로 뭔가를 할 수는 없다.
=> 이렇게 blueprint 역할을 하는 class로부터 생성된 object를 instance라고 한다.
class User {
constructor(name) {
this.userName = name;
}
sayHello() {
console.log(`Hello, my name is ${this.userName}`);
}
}
const sexyUser = new User(“Nicolas”); // new 를 사용해서 instance를 생성한다
const uglyUser = new User(“las”);
console.log(sexyUser.userName, uglyUser.userName);
sexyUser.sayHello();
2. Extending Classes
class User {
constructor(name, lastName, email, password) {
this.userName = name;
this.lastName = lastName;
this.email = email;
this.password = password;
}
sayHello() {
console.log(`Hello, my name is ${this.userName}`);
}
getProfile() {
console.log(`${this.userName} ${this.email} ${this.password}`)
}
updatePassword(newPassword, currentPassword) {
if(currentPassword === this.password) {
this.password = newPassword;
}else {
console.log(“Can’t change password”);
}
}
}
const sexyUser = new User(“Nicolas”, “Serrano”, “nico@com”, 1234);
sexyUser.getProfile();
console.log(sexyUser.password); // 1234
sexyUser.updatePassword(“hello”, “1234”);
console.log(sexyUser.password); // hello
----------------------------------------
클래스를 만들때, extends를 사용해서 기존의 클래스 내용을 가져올 수가 있다.
class Admin extends User {
DeleteWebsite() {
console..log(“Deleting the whole website…”);
}
}
const sexyAdmin = new Admin(“Nicolas”, “Serrano”, “nico@com”, “1234”);
sexyAdmin.deleteWebsite();
console.log(sexyAdmin.email);
3. super
앞에서 작성한 코드들을 조금 리팩토링 해보자.
class User {
constructor(options) { // 이후 디스트럭쳐링을 사용해서 호출 할 것임
this.userName = options.userName;
this.lastName = options.lastName;
this.email = options.email;
this.password = options.password;
}
sayHello() {
console.log(`Hello, my name is ${this.userName}`);
}
getProfile() {
console.log(`${this.userName} ${this.email} ${this.password}`)
}
updatePassword(newPassword, currentPassword) {
if(currentPassword === this.password) {
this.password = newPassword;
} else{
console.log(“Can’t change password”);
}
}
}
.........................Ongoing.........................
.........................Ongoing.........................
.........................Ongoing.........................
'PROGRAMING > Javascript' 카테고리의 다른 글
Javascript ES6 문법 총정리(1) (0) | 2020.08.01 |
---|---|
Javascript 런타임 (0) | 2019.10.10 |