ES6(ECMAScript 2015)는 ECMAScript 표준의 최신 버전이다.
ES6는 새로운 언어 기능이 포함된 주요 업데이트이며, 2009년에 표준화된 ES5 이후로 언어 기능에 대한 첫 업데이트이기도 하다. ES5 이하 명세에서 문제가 되었던 부분들이 해결되었고 많은 기능들이 추가되었다. 이는 가독성과 유지보수성 향상으로 이어졌다.
React나 Vue 등의 라이브러리들도 이에 맞춰 개발 환경을 ES6로 바꾸게 되었고 이러한 이유로 인해 우리는 ES6에 주목하고 관심을 갖게 되었다.
ES6는 아래의 새로운 기능들을 포함하고 있다.
- const and let
- Arrow functions(화살표 함수)
- Template Literals(템플릿 리터럴)
- Default parameters(기본 매개 변수)
- Array and object destructing(배열 및 객체 비구조화)
- Import and export(가져오기 및 내보내기)
- Promises(프로미스)
- Rest parameter and Spread Operator(나머지 매개 변수 및 확산 연산자)
- Classes(클래스)
const and let
let은 변수를 위해 사용한다. 새로운 값을 가질 수도 있고 값을 재할당할 수도 있다.
const는 상수(변하지 않는 값)를 위해 사용한다. 따라서 재할당이 금지된다. 이 때 주의할 점은 const는 반드시 선언과 동시에 할당이 이루어져야 한다는 것이다.
const 변수의 타입이 객체인 경우, 객체에 대한 참조를 변경하지 못한다. 하지만 할당된 객체의 내용(프로퍼티의 추가, 삭제, 변경)은 변경할 수 있다.
객체의 내용이 변경되더라도 객체 타입 변수에 할당된 주소값은 변경되지 않기 때문에 객체 타입 변수 선언에는 const를 사용하는 것이 좋다.
var vs let, const
ES6에서 추가된 const와 let은 기존에 있던 var 키워드에서 있던 문제를 해결하기 위해 등장했다.
대부분의 프로그래밍 언어는 블록 레벨 스코프를 따르지만 자바스크립트는 기본적으로 함수 레벨 스코프를 따른다.
- 함수 레벨 스코프(Function-level scope): 함수 내에서 선언된 변수는 함수 내에서만 유효. 함수 외부에서는 참조할 수 없다.
- 블록 레벨 스코프(Block-level scope): 모든 코드 블록(함수, if, for, while, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다.
var foo = 123; // 전역 변수
console.log(foo); // 123
{
var foo = 456; // 전역 변수
}
console.log(foo); // 456
위와 같이 var은 블록 레벨 스코프를 가지지 않기 때문에 코드 블록 내에 foo는 전역 변수이므로 전역 변수로 먼저 선언되어 있던 foo의 값 123을 새로운 값 456으로 재할당하여 덮어쓴다.
하지만 let과 const는 블록 스코프를 갖는다.
let foo = 123; // 전역 변수
{
let foo = 456; // 지역 변수
let bar = 456; // 지역 변수
}
console.log(foo); // 123
console.log(bar); // ReferenceError: bar is not defined
위 예시에서 코드 블록 내에 선언된 변수 foo는 블록 레벨 스코프를 갖는 지역 변수이다. 전역에서 선언된 변수 foo와는 다른 별개의 변수이다. 따라서 전역 foo의 값을 변경시키지도 않고, 지역 변수로 선언했던 변수 bar도 전역에서는 참조할 수 없다.
또한 var 키워드로는 동일한 이름을 갖는 변수를 중복해서 선언할 수 있었지만 let, const 키워드로는 동일한 이름을 갖는 변수를 중복해서 선언할 수 없다.
var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어지는 식으로 변수 호이스팅이 이루어 진다. 하지만 let과 const는 선언 단계와 초기화 단계가 분리되어 진행되기 때문에 초기화 이전에 변수에 접근하려고 하면 참조 에러가 발생한다.
Arrow functions(화살표 함수)
전통적인 함수표현의 간편한 대안이다. => 로 사용할 수 있다. 화살표 함수의 기본 문법은 아래와 같다.
// 매개변수 지정 방법
() => { ... } // 매개변수가 없을 경우
x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.
// 함수 몸체 지정 방법
x => { return x * x } // single line block
x => x * x // 함수 몸체가 한줄의 구문이라면 중괄호를 생략 가능. 암묵적으로 return된다.
화살표 함수는 익명 함수로만 사용할 수 있기 때문에 호출을 위해서 함수 표현식을 사용한다.
const pow = x => x * x;
console.log(pow(10)); // 100
this
일반 함수와 화살표 함수의 가장 큰 차이점은 this이다.
일반 함수의 this
자바스크립트의 경우 함수 호출 방식에 의해 this에 바인딩할 객체가 동적으로 결정된다. 다시 말해, 함수를 선언할 때 결정되는 것이 아니고, 함수를 호출할 때 어떻게 호출되었는지에 따라 결정되는 것이다.
화살표 함수의 this
화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다. 일반 함수와는 달리 화살표 함수의 this는 언제나 상위 스코프의 this를 가리키고, 이를 Lexical this라 한다.
화살표 함수는 call, apply, bind 메소드를 사용해서 this를 변경할 수 없다.
화살표 함수를 사용해서는 안되는 경우를 살펴보자.
화살표 함수는 Lexical this를 지원하므로 콜백 함수로 사용하기 편리하다. 하지만 화살표 함수를 사용하는 것이 오히려 혼란을 불러오는 경우도 있으니 주의해야 한다.
// Bad
const person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi(); // Hi undefined
화살표 함수로 메소드를 정의하는 것은 피해야 한다. 위 예시를 보면 메소드로 정의한 화살표 함수 내부의 this는 메소드를 소유한 객체, 즉 메소드를 호출한 객체 person을 가리키지 않고 상위 컨택스트인 전역 객체 window를 가리킨다. 따라서 화살표 함수로 메소드를 정의하는 것은 바람직하지 않다. 이런 경우에는 아래와 같이 메소드를 위한 단축 표기법인 ES6의 축약 메소드 표현을 사용하는 것이 좋다.
// Good
const person = {
name: 'Lee',
sayHi() { // === sayHi: function() {
console.log(`Hi ${this.name}`);
}
};
person.sayHi(); // Hi Lee
https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/javascript/es6.md
https://poiemaweb.com/es6-block-scope
https://poiemaweb.com/es6-arrow-function
'FE > Javascript' 카테고리의 다른 글
[JS] 자바스크립트의 This (0) | 2022.12.27 |
---|---|
[JS] ES6의 특징 (2) - 템플릿 리터럴, 반복자, for ... of (0) | 2022.03.07 |
[JS] 호이스팅(Hoisting) (0) | 2022.02.19 |
[JS] 자바스크립트로 모멘텀(Momentum) 만들기 (0) | 2021.09.07 |
[JS] filter 함수란? (0) | 2021.09.02 |