https://www.youtube.com/watch?v=TTLHd3IyErM - 드림코딩 Front-end 로드맵 영상
JavaScript
1. ES6+ Syntax
2015년 이후 ES6가 등장하며 큰 변화를 겪은 이후, ECMA가 발표하는 매년 새로운 자바스크립트 표준. (ES6 이후 발표된 ES 문법을 ES6+로 표기)
.
용어 정리
Prototype
자바스크립트의 모든 객체는 Prototype 객체를 가지고 이 Prototype 으로부터 프로퍼티와 메소드를 상속 받는다.
const obj = new Object(); // Object.prototype
const arr = new Array(); // Array.prototype
const date = new Date(); // Date.prototype
Hoisting
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 말한다. var 로 선언하는 겨우 호이스팅 시 선언과 undefined 로 초기화하는 과정까지 일어나지만 let, const는 선언만 진행되고 초기화는 일어나지 않는다. 또한, 함수를 변수로 선언할 경우에는 호이스팅이 일어나지 않는다.
console.log(test) // undefined
var test = 'test'
console.log(test) // test
/*==========================*/
console.log(test) // Error
let test = 'test'
/*==========================*/
test() // test
function test() {
console.log('test')
}
/*==========================*/
test() // Error
const test = function () {
console.log('test')
}
Scope
직역하면 '범위'라는 뜻으로 변수에 접근할 수 있는 범위를 말한다. JavaScript 에서는 전역 스코프와 지역 스코프가 있는데 함수 스코프나 블록 스코프 처럼 일정 지역에서만 사용 가능한 것은 지역 스코프라 하고 어느 곳에서나 해당 변수에 접근 가능한 것을 전역 스코프라고 한다.
const a = 1 // 전역 스코프
function test1 () {
const a = 10 // 지역 스코프 (함수 스코프)
console.log(a)
}
function test2 () {
console.log(a)
}
test1() // 10
test2() // 1
console.log(a) // 1
Closure
클로저는 함수와 함수가 선언된 어휘적 환경의 조합으로 자신이 생성될 때의 Lexical 환경을 기억하는 함수를 말한다. Lexical 환경이란 생성된 시점의 유효 범위(Scope) 내에 있는 모든 지역 변수로 구성된다.
function sum(x) {
let y = 10
return function (z) {
y = 20
return x + y + z
}
}
const sum5 = sum(5) // sum5 에 x = 5 와 y = 20 의 환경이 저장된다.
const sum10 = sum(10) // sum10 에 x = 10 와 y = 20 의 환경이 저장된다.
console.log(sum5(100)) // 125 = 5 + 20 + 100
console.log(sum10(100)) // 130 = 10 + 20 + 100
.
ES6 (2015)
let, const 키워드
블록스코프를 가지고 재선언 불가 재할당 가능한 let 변수 선언 키워드와 상수 선언 키워드 cont
// ES5
var test = 1;
test = 'abc';
// ES6
let test = 1;
test = 'abc';
const test2 = 1;
test2 = 'abc'; // error!
Array functions(화살표 함수)
// ES5
function example(test) {
return test;
}
console.log(example('test')); // test
// ES6
const example = (test) => {
return test;
}
console.log(example('test')); // test
const example = (test) => test;
console.log(example('test')); // test
Template Literals(템플릿 리터럴)
``(back tick) 안에서 ${} 내부에 자바스크립트 표현식 사용 가능
// ES5
var str1 = ', ';
var str2 = 'World!';
var str3 = 'Hello' + str1 + str2; // Hello, World!
// ES6
const str1 = ', ';
const str2 = 'World!';
const str3 = `Hello${str1}${str2}`; // Hello, World!
Default parameters(기본 매개 변수)
// ES5
function example(a, b) {
var a = a || 100;
var b = b || 200;
return a + b;
}
console.log(example(1)); // 201
// ES6
const example = (a = 100, b = 200) => a + b;
console.log(example()) // 300
Array and Object destruction(배열 및 객체 비구조화)
비구조화를 통해 배열 또는 객체의 값을 새 변수에 더 쉽게 할당할 수 있다.
// ES5
var contacts = {
familyName: '김',
name: '철수',
age: 25
};
var familyName = contacts.familyName;
var name = contacts.name;
var age = contacts.age;
console.log(familyName); // 김
console.log(name); // 철수
console.log(age); // 25
// ES6
const contacts = {
familyName: '김',
name: '철수',
age: 25
};
const { familyName, name, age } = contacts;
console.log(familyName); // 김
console.log(name); // 철수
console.log(age); // 25
Promise(프로미스)
https://kimby.tistory.com/15 참고
const url = 'https://api.test.com/get';
const getData = (url) => {
return fetch(url);
};
getDate(url)
.then(data => data.json())
.then(result => console.log(result));
.catch(error => console.log(error));
Rest parameter and Spread operator
const arr = ['Hello', 'World', 'This', 'is', 'Spread', 'Operator'];
const [ val1, val2, ...rest ] = arr;
const func = (arr) => arr.join(" ");
console.log(func(rest)); // This is Spread Operator
const func2 = (...arr) => arr.join(" ")
console.log(func(arr)); // Hello World This is Spread Operator
Class(객체)
class myClass {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
const user = new myClass('철수', 25);
console.log(user.name); // 철수
console.log(user.age); // 25
String Method (includes, startsWith, endsWith)
포함되었는지(includes), 시작하는지(startsWith), 끝나는지(endsWith) 확인하여 boolean 타입을 return
const str = 'Hello World This is String Method';
str.includes('String'); // true
str.startsWith('Hello'); // true
str.endsWith('Method'); // true
.
ES7 (2016)
Array.prototype.includes
배열에 특정 원소가 포함되어 있는지 확인하는 메소드. 2번째 인자로 index를 전달하면 해당 index부터 검색할 수 있다.
const numbers = [2, 4, 6, 8];
numbers.includes(2); // ture
numbers.includes(3); // false
numbers.includes(4, 1) // true
numbers.includes(4, 2) // false
지수 연산자
// ES7 이전
Math.pow(2, 2); // 4
Math.pow(2, 3); // 8
// ES7
2**2; // 4
2**3; // 8
.
ES8 (2017)
문자열 패딩
문자열 끝 부분이나 시작 부분을 다른 문자열로 채워 주어진 길이의 새로운 문자열을 생성
const hello = 'Hello';
hello.padStart(6); // " Hello"
hello.padEnd(6); // "Hello "
hello.padStart(3); // "Hellow"
hello.padEnd(10, '*') // "Hello*****"
Object.entries() & Object.values()
const obj = {
str: 'String',
arr: ['Array']
}
Object.entries(obj);
/*
[
['str', 'String'],
['arr', ['Array']]
]
*/
Object.values(obj);
/*
[
'String',
['Array']
]
*/
Trailing Comma (Function)
배열 및 객체에 도입된 Trailing Comma가 함수에도 도입 (Trailing Comma - MDN)
function f(p) {}
function f(p,) {}
(p) => {};
(p,) => {};
async / await 문법
https://kimby.tistory.com/17 참고
const url = 'https://api.test.com/get';
const getData = async (url) => {
return await fetch(url);
};
try {
data = await getData();
console.log(data.json);
} catch (err) {
console.log(err);
}
.
ES9 (2018)
Rest parameter and Spread operator (Object)
const obj = {
a: 1,
b: 3,
c: 'str',
d: 100
};
const { val1, val2, ...rest } = obj
const spread = {
...obj,
a: 10,
e: 30,
}
console.log(rest);
/*
{
'c': 'str',
'd': 100
}
*/
console.log(spread);
/*
{
'a': 10,
'b': 3,
'c': 'str',
'd': 100,
'e': 30
}
*/
Promise.prototype.finally()
finally 메소드는 Promise의 성공 여부와 상관없이 무조건 콜백이 실행. 성공 여부와 관계 없기 때문에 아무런 인자를 받지 못함. finally 이후 다시 then, catch를 사용 가능하지만 finally의 반환값이 아닌 이전 반환값을 인자로 받게 된다.
const promise = new Promise((resolve, reject) => {
resolve();
});
promise.then(() => {
console.log('1'); // 1
return 'then';
}).finally(res => {
console.log(2, res); // 2 undefined
return 'finally';
}).then(res => {
console.log(3, res); // 3 then
})
.
ES10 (2019)
Array.prototype.flat() & Array.prototype.flatMap()
const arr1 = [1, 2 ,[3, 4, [5, 6]]];
const arr2 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
const arr3 = [1, 2, , 4, 5];
arr1.flat(); // [1, 2, 3, 4, [5, 6]]
arr1.flat(2); // [1, 2, 3, 4, 5, 6]
arr2.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr3.flat() // [1, 2, 4, 5]
const arrMap = ['Hello World !!!', '', 'JS'];
arrMap.map(item => item.split(' ')); // [['Hello', 'World', '!!!'], [''], ['JS']]
arrMap.flatMap(item => item.split(' ')); // ['Hello', 'World', '!!!', '', 'JS']
Object.fromEntries()
키/값 쌍이 포함된 iterable을 객체로 변환
const keyVal = [
['key1', 'val1'],
['key2', 'val2']
];
const obj = Object.fromEntries(keyVal);
console.log(obj); // { 'key1': 'val1', 'key2': 'val2' }
String.prototype.trimStart() & String.prototype.trimEnd()
const str = ' Hello Word !!! ';
console.log(str); // ' Hello Word !!! '
console.log(str.trimStart()); // 'Hello Word !!! '
console.log(str.trimEnd()); // ' Hello Word !!!'
선택적 catch 할당
ES10 이전에는 catch절에 항상 예외 변수를 포함해야 하지만, ES10부터는 이를 생략할 수 있다.
try {
...
} catch {
...
}
Function.prototype.toString()
ES10에서부터 함수의 toString 메소드에 주석 등도 포함
function sum(a, b) {
return a+b;
// 주석
}
console.log(sum.toString());
// 'function sum(a, b) { return a+b; // 주석 }'
.
ES11 (2020)
Dynamic import
필요할 때 모듈을 동적으로 가져올 수 있다.
if (condition1 && condition2) {
const module = await import('path/module.js');
module.doSomething();
}
Optional Chaining
참조가 nullish(null or undefined)라면 에러가 발생하는 것이 아닌 undefined를 리턴
const adventurer = {
name: 'Alice',
cat: {
name: 'Dinah'
}
};
const catName = adventurer.cat?.name;
console.log(catName); // 'Dinah'
const dogName = adventurer.dog?.name;
console.log(dogName); // undefined
Promise.allSettled()
모든 Promise들이 완료될 때까지 기다렸다가 각각의 결과를 설명하는 객체 배열을 반환.
const promiseArr = [
new Promise((resolve, reject) => setTimeout(resolve, 1000, 'abc')),
new Promise((resolve, reject) => setTimeout(reject, 2000)),
new Promise((resolve, reject) => setTimeout(resolve, 3000)),
];
Promise.allSettled(promiseArr).then(data => console.log(data));
/*
[
{
'status': 'fulfilled',
'value': 'abc'
},
{
'status': 'rejected'
},
{
'status': 'fulfilled'
}
]
*/
Null coalescing operator
왼쪽 피연산자가 nullish일 때 오른쪽 피연산자를 반환하고 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자. 왼쪽 피연산자가 falsy일 때 오른쪽 피연산자를 반환하는 ||(or)와 대조된다.
const foo = null ?? 'default string';
console.log(foo); // 'default string'
const baz1 = 0 ?? 42;
console.log(baz1); // 0
const baz2 = 0 || 42;
console.log(baz2); // 42
String.prototype.matchAll()
지정된 정규식에 대해 문자열과 일치하는 모든 결과의 iterator를 반환하는 메소드
const regEx = /[a-d]/g;
const str = 'Lorem ipsum dolor sit amet';
const result = str.matchAll(regEx);
console.log(result.next()); // { 'value': ['d'], 'done': false }
console.log(result.next()); // { 'value': ['a'], 'done': false }
console.log(result.next()); // { 'done': true }
.
ES12 (2021)
String.prototype.replaceAll()
문자열의 지정한 모든 문자열을 특정 문자열로 변경(replace 메소드의 확장)
const str = 'I like my dog, my dog is very cute.';
const newStr = str.replaceAll('dog', 'cat');
console.log(newStr); // 'I like my cat, my cat is very cute.'
Promise.any()
주어진 promise 중 하나라도 성공하면 실행을 완료하지만, 그렇지 않다면 모든 promise가 실패할 때까지 계속 진행. 하나라도 성공 혹은 실패할 시 종료되는 Promise.rase()와 차이가 있다.
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 500, 'slow'));
const promise4 = new Promise((resolve, reject) => setTimeout(reject, 100, 'quick'));
const promise5 = new Promise((resolve, reject) => setTimeout(reject, 500, 'quick'));
const promises1 = [promise1, promise2, promise3];
const promises2 = [promise1, promise4, promise5];
Promise.any(promises1).then((value) => console.log(value)).catch((err) => console.log(err));
// 'quick' - 100ms
Promise.any(promises2).then((value) => console.log(value)).catch((err) => console.log(err));
// Error: All promises were rejected - 500ms
논리 연산자와 할당 표현식
const a = { duration: 50, title: '' };
a.duration ??= 10; // a.duration = a.duration ?? 10
console.log(a.duration); // 50
a.speed ??= 25; // a.speed = a.speed ?? 25
console.log(a.speed); // 25
a.duration &&= 60; // a.duration = a.duration && 60
console.log(a.duration); // 60
a.title ||= 'Title'; // a.title = a.title || 'Title'
console.log(a.title); // 'Title'
숫자 구분 기호
_(언더바)를 사용하여 큰 자릿수 숫자를 구분 가능
const x = 100_000_000;
console.log(x); // 100000000
참조
https://hanamon.kr/javascript-es6-문법
https://velog.io/@kimhscom/JavaScript-자주-사용하는-ES6-문법-정리
https://teamdable.github.io/techblog/after-es6