기존 함수와의 차이점은 문법적인 것도 분명하나 사실은 this binding 부분에서 차이점이 있다.
기존 함수는 호출방식에 따라 바인딩이 결정된다.
일반 함수는 함수를 선언할 때 this 에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this 에 바인딩할 객체가 동적으로 결정된다고 하였다.
화살표 함수는 함수를 선언할 때 this 에 바인딩할 객체가 정적으로 결정된다. 동적으로 결정되는 일반 함수와는 달리 화살표 함수의 this 언제나 상위 스코프의 this 를 가리킨다. 이를 Lexical this라 한다.
화살표 함수는 call, apply, bind 메소드를 사용하여 this 를 변경할 수 없다.
Arrow Function 으로 메서드 등 선언하는 것은 자제하자. 전역 스코프를 가르키기 때문이다.
메서드를 선언시 축약 표현으로 메서드를 사용하자.
let person = {
name: 'Lee',
sayHi: () => console.log(`Hi ${this.name}`)
};
person.sayHi(); // undefined
person = {
name: 'Lee',
sayHi() { console.log(`Hi ${this.name}`); } // 축약 메서드 표현
};
person.sayHi(); // Hi Lee
이벤트 할당도 동일한 문제를 가지고 있으니 일반 함수로 사용을 권장한다.
생성자 함수로 사용할 수 없다. 프로토타입을 가지고 있지 않기 때문이다.
for..of
for…of 문은 내부적으로 이터레이터의 next 메소드를 호출하여 이터러블을 순회하며 next 메소드가 반환한 이터레이터 리절트 객체의 value 프로퍼티 값을 for…of 문의 변수에 할당한다. 그리고 이터레이터 리절트 객체의 done 프로퍼티 값이 false 이면 이터러블의 순회를 계속하고 true 이면 이터러블의 순회를 중단한다.
// 배열
for (const item of ['a', 'b', 'c']) {
console.log(item);
}
// 문자열
for (const letter of 'abc') {
console.log(letter);
}
// Map
for (const [key, value] of new Map([['a', '1'], ['b', '2'], ['c', '3']])) {
console.log(`key : ${key} value : ${value}`); // key : a value : 1 ...
}
// Set
for (const val of new Set([1, 2, 3])) {
console.log(val);
}
// 내부적으로 어떻게 동작하는지 for 로 표현하면 다음과 같다.
// 이터러블
const iterable = [1, 2, 3];
// 이터레이터
const iterator = iterable[Symbol.iterator]();
for (;;) {
// 이터레이터의 next 메소드를 호출하여 이터러블을 순회한다.
const res = iterator.next();
// next 메소드가 반환하는 이터레이터 리절트 객체의 done 프로퍼티가 true가 될 때까지 반복한다.
if (res.done) break;
console.log(res);
}
Destructuring
Array Destructuring
ES6의 배열 디스트럭처링은 배열의 각 요소를 배열로부터 추출하여 변수 리스트에 할당한다. 이때 추출/할당 기준은 배열의 인덱스이다.
const arr = [1, 2, 3];
/*
배열의 인덱스를 기준으로 배열로부터 요소를 추출하여 변수에 할당
변수 first, second, third 선언되고 arr(initializer(초기화자))가 Destructuring(비구조화, 파괴)되어 할당된다.
*/
const [first, second, third] = arr;
/*
디스트럭처링을 사용할 때는 반드시 initializer(초기화자)를 할당해야 한다.
const [first, second, third]; // SyntaxError: Missing initializer in destructuring declaration
*/
console.log(first, second, third); // 1 2 3
Object Destructuring
ES6의 객체 디스트럭처링은 객체의 각 프로퍼티를 객체로부터 추출하여 변수 리스트에 할당한다. 이때 할당 기준은 프로퍼티 이름(키)이다.
function defaultValueInParameter(x=0, y=1){
return x+y;
}
또한 기본값을 정하여도 length, arguments 에 영향을 미치지 않는다
Rest Parameter
기본적인 형식은 다음과 같다.
// 일반적인 형태이며 가변인자를 배열 형태로 받는다.
function restParameterFunction(...rest){
console.log(Array.isArray(rest));
console.log(rest);
return rest.reduce((first, second) => first + second);
}
// 반드시 제일 마지막에 위치하지 않으면 Syntax Error 발생
function parameterCombination(first,second, ...rest){
console.log(Array.isArray(rest));
console.log(rest);
}
Spread Syntax
정의된 설명으론 '이터러블' 인 대상을 개별 요소로 분할한다.
모양은 Rest Syntax 와 동일하나 일반적인 객체는 type error 을 발생시킨다.
console.log(...[1, 2, 3]); // 1, 2, 3
console.log(...'Hello'); // H e l l o
console.log(...new Map([['a', '1'], ['b', '2']])); // [ 'a', '1' ] [ 'b', '2' ]
console.log(...new Set([1, 2, 3])); // 1 2 3
console.log(...{ a: 1, b: 2 }); // 이터러블이 아닌 일반 객체는 Spread 문법의 대상이 될 수 없다.
일반 함수에 argument 로 Spread 형태의 배열을 전달되는 경우 순차적으로 해당 함수의 파라미터에 할당한다.
const arr = [1, 2, 3];
function foo(x, y, z) {
console.log(x);
console.log(y);
console.log(z);
}
foo(...arr);