ES6 Playing with Syntax
Chrome(46.0.2490.71)에서 ES6 사용하기
ES6을 Chrome 에서 시험적으로 사용하기 위해서는 #enable-javascript-harmony flag를 사용으로 바꾸어야 한다.
또한, chrome에서는 strict mode가 아니면 다음과 같은 SyntaxError가 발생한다. 꼭! “use strict”; 를 추가하자.
let keyword
블록 내부에서만 변수가 유효하다.
- block scoped 변수 선언에 사용한다.
- 재선언시 TypeError가 발생한다.
let으로 선언한 변수를 한번 실행하면, 페이지가 재로딩될때까지 재정의할수 없다. 정의하면 다음과 같은 TypeError가 발생한다.
js 라이브러리같은 경우에는 종종 중복로딩이 되는 경우가 있는데, let 키워드를 사용하게 되면 문제가될 가능성이 높을것 같다. let 키워드는 전역 사용을 지양해야할 것 같다.
Chrome 46.0.2490.71 에서는 let을 전역으로 사용할 경우, window에 해당 변수가 할당되지 않았다. 반면, Firefox 41.0.2에서는 window에 전역영역에 let으로 선언할 경우, window에 변수가 할당되었다.
let a = “전역";
// Chrome은 “전역" undefined
// Firefox는 “전역" “전역"
console.log(a, window.a);
const keyword
const를 사용하면 한번 지정한 값을 변경할 수 없다. 책에서는 Reference Error Exception이 발생한다고 하지만, 실제로는 에러 없이 값이 갱신되지 않는다. 객체를 선언시에는 객체의 레퍼렌스만 갱신되지 않고, 객체의 내용은 변경이 된다.
- 한번 지정한 값을 변경 할 수 없다.
- block scoped (?) 변수 선언에 사용한다. (Chrome 46.0.2490.71에서는 function scoped, Firefox 41.0.2에서는 blocked scoped)
- 재선언시 TypeError가 발생한다.
위에서 발생한 메세지와 다르게, strict mode를 선언하지 않아도, const 키워드는 사용할수 있었다.
Default Parameter value
ES6에서는 파라미터의 초기값을 지정할수 있다.
아쉽지만, Chrome에서는 아직 미지원상태이다.
The spread operator
‘…’ 으로 표기하는 이 표현식은 array와 같이 iterable한 객체들을 쫙~ 펼치는 표현식이다. 예를 살펴보면 간단히 알수 있다.
The rest parameter
spread operator의 표기법을 함수 뒤에 사용하면, ES6 전에 arguments를 이용하여 여분의 파라미터를 받았던 방식을 보다 쉽게 사용할수 있다.
arguments는 배열이 아니기 때문에 배열로 변환해서 사용해야 했지만, rest parameter는 array이기 때문에 훨~씬 사용하기 쉽다.
// 예전 방식
Array.prototype.slice.call(arguments);
The destructuring assignment
배열이나 객체를 한꺼번에 선언하는 문법들이 ES6에서 지원한다. Python을 배운 사람들에게 친숙한 표현법 인것 같다.
아쉽지만 현재 크롬에서는 구현이 되어 있지 않다.
The destructuring assignment (Array)
array 타입에는 다음과 같이 default parameter, spread, 중첩과 같은 다양한 표현을 함께 사용할수 있다.
The destructuring assignment (Object)
object 타입에서도 다음과 같이 default parameter, 중첩과 같은 다양한 표현을 함께 사용할수 있다.
The arrow functions
ES6에서는 익명함수를 간단히 만드는 새로운 문법을 사용한다. 바로 arrow function 이다. “=>” 와 같이 표기한다.
() => {} // 파라미터가 없는 경우
파라미터1 => {}
(파라미터1, 파라미터2) => {}() => 반환값 // 파라미터가 없는 경우, {}이 생략된 경우, 함수의 몸체는 반환값이 된다.
파라미터1 => 반환값
(파라미터1, 파라미터2) => 반환값
arrow function은 전통적인 function과 몇가지 다른 특성이 있다.
- arrow function은 전통적인 function 과 다르게 객체의 생성자로 사용할수 없다. 순수한 function 고유의 역할(?)을 한다.
- arrow function의 this는 전통적인 function 의 this가 가리키는 것과 다르다.
전통적인 Function의 this
전통적인 function에서의 this는 그 함수를 호출한 대상을 참조한다. 즉, 호출 시점에 따라 this가 달라진다. 호출한 대상이 없다면, this는 global(window)이 된다.
target.method같이 호출하는 경우, this는 target
target이 없는 경우에는 global
그 예는 다음과 같다.
- 기본적으로 this는 global이다.
- 함수 내부에서 선언된 함수의 this는 global 이다.
- 객체 메소드 내부의 this는 해당 메소드를 호출한 부모 객체이다.
- 생성자 함수 코드 내부의 this는 새로 생성된 객체이다.
- 프로토타입 객체 메소드 내부의 this는 해당 메소드를 호출한 부모 객체이다.
- 이벤트 핸들러의 this는 이벤트 핸들러를 붙인 엘리먼트이다.
Arrow Function의 this
arrow function의 this는 전통적인 function의 this와 차이가 난다. arrow function은 자신의 this를 가지지 않고, 항상 arrow function을 감싸는 외부 scope를 사용한다.
위 예에서 f1에서 호출한 this는 obj를 가리키는게 아니라, f1을 감싸는 obj의 scope 영역인 global을 참조한다.
이를 이용하면 예전에 지역변수(that, self,…)에 this를 넣어서 써야하는 코딩 스타일을 바꿀수 있다. 이것도 꽤 많이 사용할것 같다.
The Enhanced Object literals
- 변수의 이름을 object의 키로 할당 할수 있다. 코드를 보면 쉽게 이해할수 있다.
let x =1, y =2;
let obj = {x, y}; // {x:1, y:2};
- 메소드를 key/value형태가 아닌 명시적으로 ‘이름이 있는 function’으로 지정할 수 있다.
let obj = {
nameFunc() { console.log(“오마이갓"); }
};
obj.nameFunc();
- 동적인 key를 지정할수 있다. 개인적으로 이 문법은 정말 많이 쓸것 같다.
let obj = { [“first” + “name”] : “son” };
결론….
1장을 읽고 얻은 느낌은 크게 2가지이다.
- ES6이전의 JavaScript로 작성하는 경우, 코딩을 잘못해서 발생할 수 있는 여러 문제를 인터프리터 단계에서 막도록 구성한 것은 바람직해보인다. 하지만, 개인적으로 받은 느낌은 100%막는 것도 아니고 또 100%도 풀어준 것도 아니어서 큰 변화의 느낌은 솔직히 없다.
- 문법의 방향이 가급적 간단히 쓰는 형태를 취하고 있다. 요즘 Python이 대세인 이유도 아마 여기에 있지 않나 싶다. 매력적이다. 그런데 너무 줄이다 보니, 오히려 코드 가독성이 떨어지는 경우도 있을것 같다. 적당히 써야될것 같다.