2015년, 자바스크립트에 큰 변화가 생겼다. 다른 언어들의 장점을 본따 편리한 기능이 많이 추가된 것이다. 이를 ES2015라고 부른다. 2015년을 기점으로 매년 문법 변경 사항이 발표되고 있고, 현재 기준(2022년) ES2022까지 발표되었다. 이 글에서는 ES2015 기준으로 다룰 예정이다.
💡 Node 6버전 이상부터 ES2015 문법을 사용할 수 있다
기존 자바스크립트에서는 var로 변수를 선언했다. 하지만 const와 let이 등장했다. var와 const,let의 차이점을 코드를 통해 알아보자.
if (true) {
var x = 3;
const y = 3;
let z = 3;
}
console.log(x); // 3
console.log(y); // Uncaught ReferenceError
console.log(z); // Uncaught ReferenceError
var로 선언된 x는 정상 출력되지만, 각각 const와 let으로 선언된 y와 z는 오류를 발생시킨다. 이는 스코프
의 차이다. var은 함수 스코프
를 가진다. if문 등의 블록과 상관없이 함수의 지역변수에 접근 가능한 것이다. var와 다르게 const와 let은 블록 스코프
를 갖는다. 따라서 블록 안에서 선언 시 블록 밖에서 접근 불가능하다. 이러한 장점을 통해 호이스팅과 같은 문제도 해결되고 코드 관리도 수월해진다.
그럼 const와 let의 차이는 무엇일까? 다른 언어와 마찬가지로 const는 한 번 값을 할당하면 다른 값을 할당할 수 없고, 선언과 동시에 초기화를 해줘야 하는 상수
다. let은 초기화 이후에 다른 값을 할당할 수 있다.
호이스팅이란?
: 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것
- var로 선언한 변수: undefined로 변수를 초기화
- const, let으로 선언한 변수: 변수를 초기화 하지 않음
ES2015에는 백틱을 활용한 템플릿 문자열이 추가되었다. 아래 코드와 같이 백틱
과 ${변수}
를 활용하면 된다.
const num1 = 1;
const num2 = 2;
const num3 = 3;
console.log(`${num1} + ${num2} = ${num3}`)' // 1 + 2 = 3
- 메서드 생성 시,
콜론(:)이나 function 키워드 없이
바로 메서드 생성 가능 - 프로퍼티/메서드 생성 시,
변수
만 설정 가능 (Key: Value 불필요
) - 프로퍼티 key 이름 동적 생성
ES2015부터 객체 리터럴
방식으로 객체 생성 시, 위의 기능이 추가되었다. 아래의 코드와 주석로 확인할 수 있다.
const sampleObject = {
// 콜론과 function 키워드 사용 X
test() {
console.log("test");
},
// key:value 없이 변수 선언
sample,
// 프로퍼티 key 이름 동적 생성
[key + 7]: "test",
};
화살표 함수는 function 선언 대신 =>
기호로 함수를 선언한다. return 문을 줄일 수 있기에 코드가 깔끔해보인다.
// 일반 함수 선언
function add1(x, y) {
return x + y;
}
// 화살표 함수 선언
const add2 = (x, y) => x + y;
객체와 배열은 JS에서 가장 많이 쓰이는 자료 구조다. 개발을 하다보면 가끔 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생기기도 하는데, 이 때 객체나 배열을 변수로 분해
할 수 있게 해주는 구조분해 할당
을 ES2015부터는 사용할 수 있다.
// 객체
const SampleObject = {
test: {
value1: "abc",
value2: 1,
},
getTest: function () {
console.log(this.test.value1);
console.log(this.test.value2);
},
};
const {
getTest,
test: { value2 },
} = SampleObject;
// 배열
const arr = ["1", "2", "3", "4"];
const [first, second, , fourth] = arr; // 2번 인덱스 요소는 가져오지 않음
이제는 JS에도 클래스 문법이 추가되었다. 다른 언어와 달리 클래스 문법으로 작성됐더라도 여전히 프로토타입 기반으로 동작하지만, 대중적(?)인 문법인 만큼 코드를 작성하거나 읽을 때 이해하기 쉬울 것이다.
class Sample1 {
constructor(a, b) {
this.a = a;
this.b = b;
}
}
class Sample2 extends Sample1 {
constructor(a, b, c) {
super(a, b);
this.c = c;
}
}
JS와 node는 주로 비동기로 동작한다. 여기서 비동기 처리란 특정 동작이 완료될 때까지 기다리지 않고 다음 동작을 수행하는 것을 의미한다. 비동기 처리 때문에 콜백 함수가 자주 사용됐는데, ES2015에 포함된 프로미스
의 등장과 함께 콜백 지옥 현상을 극복
할 수 있었다.
: 자바스크립트 비동기 처리에 사용되는 객체
프로미스는 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용된다. 클라이언트가 서버에 id가 1인 어떤 데이터를 요청(request)하고 응답(response) 받는 상황을 예로 들면 아래와 같은 코드를 작성할 수 있다.
$.get('some_url/id/1', function(response) {
. . .
});
우리가 원하는 동작은 위 API가 실행돼 데이터를 받아오고 화면에 표시하는 것이다. 하지만 비동기 처리로 인해 데이터를 받아오기 전에 화면에 데이터를 표시하려고 하기 때문에 빈 화면이 표시될 수밖에 없다. 이와 같은 문제점의 해결법 중 하나가 프로미스다.
- Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태
- Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
- Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
: 새로운 프로미스를 생성하면 프로미스는 대기 상태
가 된다. 이 때 콜백 함수를 선언
할 수 있고, 인자로는 resolve
와 reject
가 있다.
new promise(function(resolve, reject) {
. . .
});
: 콜백 함수의 인자 resolve
를 실행하면 이행 상태가 되고, then()
을 이용하여 결과를 받을 수 있다.
function getData() {
return new Promise(function (resolve, reject) {
const data = 100;
resolve(data);
});
}
getData().then(function (resolvedData) {
console.log(resolvedData);
});
: reject는 실패 상태로, 오류에 대해catch
로 받을 수 있다.
function getData() {
return new Promise(function (resolve, reject) {
reject(new Error("fail"));
});
}
getData()
.then()
.catch((err) => {
console.log(err);
});
- 서적: Node.js 교과서
- Blog: joshua1988님