[React] ES6 문법 정리
참고 문헌 : Do it 리액트 프로그래밍 정석
Intro
리액트를 현업에서 주로 쓴다는 말은 들었지만 실제로 이렇게까지 써먹을 줄은 사실 잘 몰랐다. 난 분명 프론트앤드를 지망한 적이 없었으나 먹고살기 위해선 내가 해야 할 일이 프론트앤드라는 것을 인정하고 열심히 공부하는 수 밖에.
한동안 PS 위주로 포스팅을 했다. 이제부턴 기술들에 대한 포스팅을 주로 올릴까 한다.
템플릿 문자열
var string1 = 'Hello';
var string2 = 'Nice to meet you';
var result = string1 + ' ' + string2
var product = {name : 'chicken', price : '18000'};
var message = product.name + '의 가격은' + product.price + '입니다.';
var string1 = 'Hello';
var string2 = 'Nice to meet you';
var result = string1 + ' ' + string2
var product = {name : 'chicken', price : '18000'};
var message = product.name + '의 가격은' + product.price + '입니다.';
위의 코드는 우리가 흔히 보던 자바스크립트의 문자열 사용 방법들이다.
특히 후자같은 경우엔 C++에서도 주로 저런 짓을 많이했다. 상당히 불편하다.
var string1 = 'Hello';
var string2 = 'Nice to meet you';
var result = '${string1} ${string}';
var product = {name : 'chicken', price : '18000'};
var message = '${product.name} 의 가격은 ${product.price} 입니다.';
아마 파이썬에서 format 함수를 써 본 사람들은 비슷한 면을 발견할 수 있을 것이다. ES6에서는 이러한 형태의 문자열 처리를 지원한다.
전개 연산자
var array1 = ['1','2'];
var array2 = ['3','4'];
var array1 = ['1','2'];
var array2 = ['3','4'];
이 두가지 배열을 합쳐야 한다면 여러가지 방법이 있겠지만 크게 두가지 방법이 있다.
1. 일일히 값을 가져와서 하나의 큰 배열을 만든다.
2. concat을 활용한다.
하지만 ES6에서는 그렇게까지 할 필요는 없고 다음과 같이 하면 된다.
var result = [...array1, ...array2];
... 즉 전개연산자를 사용하면 데이터 전체를 다 집어넣을 수 있다.
가변 변수, 불변 변수
var num = 1;
var num = 1;
기존에 javascript는 var를 통해 변수를 선언했다. 물론 지금이라고 그렇게 하면 안되는 것은 아니다. 하지만 마치 다른 언어와 마찬가지로 가변(변할 수 있는), 그리고 불변(변하지 않는) 변수를 선언할 수 있는 키워드가 추가되었다.
let num = 2;
const num2 = 1;
let은 가변 변수, const는 불변 변수다. let은 흔히 우리가 알던 변수와 같다.
const는 불변 변수다. 하지만 값을 다시 할당할 수 없는거지 값을 바꿀 수는 있다. 내장 함수를 통해 값에 변화를 줄 수는 있다.
const data = [];
data.push(1);//[1]
data.pop();//[]
data.push(2);//[2]
data.splice(0,0,0);//[0,2]
가변 내장함수 | 무결성 내장 함수 |
---|---|
push(...items) | concat(...items) |
splice(s, c, items) | slice(0, s), concat(...items, slice(s+c) |
pop() | slice(0, len-1) |
shift() | slice(1) |
클래스
사실 기존의 javascript가 그렇게 익숙하지는 않아서 처음에 이해하기 상당히 어려웠다. ES6문법은 java가 익숙하다면 그렇게 어렵지 않다.
class shape{
static create(x, y) {return new Shape(x, y);}
name = 'shape';
constructor(x, y){
this.move(x, y);
}
move(x, y){
this.x = x;
this.y = y;
}
area(){
return 0;
}
}
기존의 java와 거의 유사하다. 이걸 기존의 문법으로 만든다면?
function Shape(x, y) {
this.name = 'Shape';
this.move(x, y);
}
Shape.create = function(x, y) {
return new Shape(x, y);
};
Shape.prototype.move = function(x, y) {
this.x = x;
this.y = y;
};
Shape.prototype.area = function() {
return 0;
};
물론 java 처럼 필드변수 따로 선언해주고 그러지는 않는다.
class Circle extend Shape{
constructor(x, y, radius){
super(x, y);
this.radius = radius;
}
area(){
if(this.radius === 0) return super.area();
return this.radius * this.radius;
}
}
상속은 이런 식으로 구현한다.
화살표 함수
var add = (first, second) =>{
return first + second;
};
var add = (first, second) => first + second;
var addAndMultiple = (first, second) => ({add : first + second, multiply : first * second});
var add = (first, second) =>{
return first + second;
};
var add = (first, second) => first + second;
var addAndMultiple = (first, second) => ({add : first + second, multiply : first * second});
이런 식으로 선언하는 함수의 장점은 다음과 같다.
1. 커링 구조에서 계단형 함수가 만들어지지 않는다.
function addNum(num){
return function(value){
return num + value;
}
}
var addNum = num => value => num + value;
- 콜백 함수의 this 범위로 생기는 오류를 피하기 위해 bind 처리를 할 필요가 없다.
class MyClass{
value = 10;
constructor(){
var add = function(first, second){
return this.value + first + second;
}
var add2 = (first, second) => this.value + first + second;
}
}
객체 확장 표현식
기존의 javascript에서는 객체와 객체의 값을 선언하기 위해 키 이름과 값을 같이 할당했다. 하지마 ㄴES6에서는 그렇게 하지 않는다.
var x = 0;
var y = 0;
var obj = {x, y};
var randomKeyString = 'other';
var combined = {
['one' + randomKeyString] : 'some value',]
};
var obj2 = {
x,
methodA() {console.log('method A');},
methodB() { return 0;},
};
구조 분해 할당
var list = [0,1];
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
var temp = item2;
item2= item1;
item1 = temp;
var obj = {
key1: 'one',
key2: 'two',
};
var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = key1;
var list = [0,1];
var item1 = list[0];
var item2 = list[1];
var item3 = list[2] || -1;
var temp = item2;
item2= item1;
item1 = temp;
var obj = {
key1: 'one',
key2: 'two',
};
var key1 = obj.key1;
var key2 = obj.key2;
var key3 = obj.key3 || 'default key3 value';
var newKey1 = key1;
이렇게 표현할 수 있는 코드를
var list = [0, 1];
var [
item1,
item2,
item3 = -1,
] = list;
[item2, item1] = [item1, item2];
var obj = {
key1: 'one',
key2: 'two',
};
var {
key1: newKey1,
key2,
key3 = 'default key3 value',
} = obj;
var [item1, ...otherItems] = [0, 1, 2];
var { key1, ...others } = { key1: 'one', key2: 'two' };
이렇게도 표현할 수 있다. || 연산자는 헷깔리기 쉬운 건데 이런 문제를 해결할 수 있다.
배열 함수
forEach()
우리가 생각하는 그 forEach 맞다.
const qs = 'banana=10&apple=20&orange=30';
function parse(qs) {
var queryString = qs.substr(1); // querystring = 'banana=10&apple=20&orange=30'
var chunks = queryString.split('&'); // chunks = ['banana=10', 'apple=20', 'orange=30']
var result = {};
for(var i = 0; i < chunks.length; i++) {
var parts = chunks[i].split('=');
var key = parts[0];
var value = Number.isNaN(Number(parts[1])) ? parts[1] : Number(parts[1]);
result[key] = value;
}
return result;
}
우선 '&' 을 기준으로 문자열을 분리하고 '='를 기준으로 문자열을 분리한 다음 key와 value로 나눈다. 그 후 해당 key값에 value를 집어넣는다.
forEach를 쓰면 굳이 저런 식으로 for문을 돌리지 않아도 된다. 뭐 사실 java든 c++이든 흔히 보던 문법 아닌가 .
function parse(qs) {
const queryString = qs.substr(1); // querystring = 'banana=10&apple=20&orange=30'
const chunks = queryString.split('&'); // chunks = ['banana=10', 'apple=20', 'orange=30']
let result = {};
chunks.forEach((chunk) => {
const [ key, value ] = chunk.split('='); // key = 'banana', value = '10'
result[key] = value; // result = { banana: 10 }
});
return result;
}
map()
Python을 써 본 사람들이라면 자주 들어봤을 함수다. 파이썬에서 map 함수가 하는 역할은 특정 형태의 값으로 변환 해주는 것이었다.
myList = [1, 2, 3, 4, 5]
def add_one(n):
return n + 1
result2 = list(map(add_one, myList))
print(myList)
print(result2)
[1,2,3,4,5]
[2,3,4,5,6]
이런 식으로 말이다. javascript도 비슷한다.
function parse(qs){
const queryString = qs.substr(1);
const chunks = qs.split('&');
const result = chunks.map((chunk) =>{
const [ key, value ] = chunk.split('=');
return {key : key, value : value };
});
return result;
}
result = [
{key : 'banana', value = '10'},
{key : 'apple', value = '20'},
{key : 'orange', value = '30'}
];
reduce
배열을 객체로 변환하고 싶을 때 사용하는 함수
function parse(qs) {
const queryString = qs.substr(1);
const chunks = queryString.split('&');
return chunks
.map((chunk) => {
const [ key, value ] = chunk.split('='); // key = 'banana', value = '10'
return { key, value }; // { key: 'banana', value: '10' }
})
.reduce((result, item) => ({
...result,
[item.key]: item.value,
}), {});
}
result : {banana : '10', apple : '20', orange : '30' }
비동기 함수
기존에 javascript는 비동기 작업을 위해 setTimeout() 형식으로 시간 지연을 주는 식으로 처리하였다.
function work1(onDone) {
setTimeout(() => onDone('작업1 완료!'), 100);
}
function work2(onDone) {
setTimeout(() => onDone('작업1 완료!'), 200);
}
function work3(onDone) {
setTimeout(() => onDone('작업3 완료!'), 300);
}
work1(function(msg1) {
console.log('done after 100ms:' + msg1);
work2(function(msg2) {
console.log('done after 300ms:' + msg2);
work3(function(msg3) {
console.log('done after 600ms:' + msg3);
});
});
});
ES6에서는 Promise 로 해결할 수 있다.
const work1 = () =>
new Promise(resolve => {
setTimeout(() => resolve('작업1 완료!'), 100);
});
const work2 = () =>
new Promise(resolve => {
setTimeout(() => resolve('작업2 완료!'), 200);
});
const work3 = () =>
new Promise(resolve => {
setTimeout(() => resolve('작업3 완료!'), 300);
})
const nextWorkOnDone = (msg1) => {
console.log('done after 100ms:' + msg1);
return work2();
};
work1()
.then(nextWorkOnDone)
.then((msg2) => {
console.log('done after 200ms:' + msg2);
return work3();
})
.then((msg3) => {
console.log('done after 600ms:' + msg3);
});
디바운스
어떤 내용을 입력하다 특정 시간동안 대기하고 있다면 마지막에 입력된 내용을 바탕으로 서버 요청을 하는 방법.
ex. 연관 검색어
export function debounde(func, delay){
let inDebounce;
return function(...args){
if(inDebounce){
clearTimeout(inDebounce);
}
inDebounce = setTimeout(
() => func(...args), delay);
}
}
const run debounce(val => console.log(val), 100);
run('a');
run('b');
run(2);
//100ms 이후 2가 출력됨.
스로틀
디바운스와 다르게 입력되는 동안에도 바로 이전에 요청한 작업을 주기적으로 실행함.
ex. 페이스북의 타임라인. 스크롤을 내리는동안 다음 내용이 계속 출력됨.
export function throttle(func, delay) {
let lastFunc;
let lastRan;
return function(...args) {
const context = this;
if (!lastRan) {
func.call(context, ...args);
lastRan = Date.now();
} else {
if (lastFunc) clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if ((Date.now() - lastRan) >= delay) {
func.call(context, ...args);
lastRan = Date.now();
}
}, delay - (Date.now() - lastRan));
}
}
}
var checkPosition = () => {
const offset = 500;
const currentScrollPosition = window.pageYOffset;
const pageBottomPosition = document.body.offsetHeight - window.innerHeight - offset;
if (currentScrollPosition >= pageBottomPosition) {
// fetch('/page/next');
console.log('다음 페이지 로딩');
}
};
var infiniteScroll = throttle(checkPosition, 300);
window.addEventListener('scroll', infiniteScroll);
Author And Source
이 문제에 관하여([React] ES6 문법 정리), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sierra9707/React-ES6-문법-정리저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)