이번 챕터에서 정리할 것은 spread 연산자와 rest 연산자, 그리고 객체 리터럴 표기법에 관련한 내용이다. 모던 JS 핵심 가이드 책을 읽으면서 공부한 내용을 실제 프로젝트 리팩토링을 할 때 적용하는 경험을 하게 되니 이론 공부가 매우 유용하다는 생각이 든다.
배열의 결합, 복사에 사용된다.
const veggie = ["tomato", "cucumber", "beans"];
const meat = ["pork", "beef", "chicken"];
const menu = [...veggie, "pasta", ...meat];
console.log(menu);
// ["tomato", "cucumber", "beans", pasta", "pork", "beef", "chicken"];
veggie와 meat 사이에 'pasta'라는 문자열을 추가하여 전체를 하나의 배열로 만들었다.
이처럼 기존에 이미 만들어진 배열들의 요소를 하나하나 가져올 때 spread 연산자를 쓰면 유용하다. (spread 연산자의 역할: 배열의 대괄호를 없앰)
중요한 파트이다. spread 연산자를 사용하면 concat 메서드를 대체할 수 있으며, 훨씬 간단하게 배열 복사가 가능하다.
원본 배열의 변경 없이 배열을 수정하려면 배열을 '복사'한 뒤 그 새로운 복사본 배열을 수정해야 한다.
기존 ES5까지는 다음처럼 빈 배열을 만들고 concat을 이용하는 두 가지 과정을 거쳐야 했다. (코드로는 한 줄이나 실제 과정은 두 번)
const veggie = ["tomato", "cucumber", "beans"];
// 배열 복사: 빈 배열을 만든 뒤, concat으로 기존 배열의 내용을 담아서 똑같은 배열을 만듦
const newVeggie = [].concat(veggie);
// 배열 수정: push로 새로운 값 추가
newVeggie.push("peas");
// 새로운 값이 추가된 배열
console.log(newVeggie); // ["tomato", "cucumber", "beans", "peas"]
// 원본 배열의 변경은 없음
console.log(veggie); // ["tomato", "cucumber", "beans"]
ES6부터는 spread 연산자를 사용하여 이 두 과정을 한 번에 할 수 있다.
const veggie = ["tomato", "cucumber", "beans"];
// 배열 복사: spread 연산자로 똑같은 배열을 만듦
const newVeggie = [...veggie];
// 배열 수정: push로 새로운 값 추가
newVeggie.push("peas");
// 새로운 값이 추가된 배열
console.log(newVeggie); // ["tomato", "cucumber", "beans", "peas"]
// 원본 배열의 변경은 없음
console.log(veggie); // ["tomato", "cucumber", "beans"]
형태로는 spread 연산자와 똑같지만 정확히 반대 기능을 한다.
spread 연산자는 배열의 대괄호를 벗겨 배열을 '확장'(인자를 하나하나 나열)하지만,
reast 연산자는 여러 개의 배열 요소를 하나로 '압축'한다.
const runners = ["Tom", "Paul", "Mark", "Luke"];
// 1등과 2등만 따로 뽑고 나머지(rest)는 losers로 처리했다.
const [first, second, ...losers] = runners;
// 현재 losers는 [Mark", "Luke"]인 상태다.
// 이 배열을 spread 연산자로 '펼쳐서' 콘솔에 출력한다.
console.log(...losers); // Mark Luke
객체 리터럴 표기법과 관련해서는 책에 3가지 팁이 소개되었다. 이 중에 key와 value가 같을 경우 key를 생략하는 문법은 기존에 알고 있었으므로 상대적으로 생소했던 2번째와 3번째 팁만 정리하였다.
ES5에서는 메서드를 이렇게 작성했다.
const person = {
name: "Yena",
greet: function() {
console.log("HiYena");
},
};
person.greet(); // HiYena
꼭 key에 콜론(':')를 붙이고 메서드는 익명함수를 작성했던 것이다. (기명함수도 가능한 걸로 알고 있다)
익명함수의 경우 호출할 때는 key 이름을 함수 이름 대신 사용한다.
ES6에서는 이 과정이 좀 더 간소화되었다.
const person = {
name: "Yena",
greet() {
console.log("HiYena");
},
};
person.greet(); // HiYena
한 마디로 'function'과 콜론(':') 부분이 생략 가능해진 것이다.
다음에 나올 화살표 함수와 비교하자면 위의 경우는 일반 함수(function)일 때이다.
화살표 함수는 '무조건 익명 함수'다. 따라서 함수를 호출할 때 위의 첫 번째 경우처럼 함수명을 대체할 key가 필요하다.
const person = {
greet: () => console.log("HiYena");
};
person.greet(); // HiYena
화살표 함수에서는 실행문이 한 줄일 경우 중괄호 생략이 가능하다.
또한 "() =>" 부분에 함수명을 넣을 수 없기 때문에 key 이름과 키를 구분해주는 콜론(":")이 꼭 필요하다.
호출은 일반 함수(function)의 경우와 동일하다.
'동적으로 생성'한다는 말은 '기존 위치에 없던 것을 새로 만들어 추가'하는 걸 말한다.
ES5에서는 객체의 프로퍼티를 동적으로 만들기 위해 다음과 같은 두 가지 과정을 거친다.
let name = "myName"; // 프로퍼티의 key로 사용할 문자열 선언
let person = {}; // 빈 객체 생성
// 빈 객체의 key 번째에 들어갈 값(value) 정의
person[name] = "Yena";
console.log(person.myName); // Yena
ES6에서는 이 과정을 한 번에 할 수 있다. 객체 리터럴을 사용하여, 마치 리액트의 JSX처럼 필요한 값을 필요한 자리에 바로 넣는다.
let name = "myName"; // 프로퍼티의 key로 사용할 문자열 선언
let person = {
[name]: "Yena",
};
console.log(person.myName); // Yena
빈 객체를 굳이 만드는 과정이 줄어들고 훨씬 직관적으로 코드 작성이 가능하다.