TIL 2020.4.29
이 페이지에서 간단히 정리할 기능들..
1. destructuring assignment
2. spread operator / rest parameters
3. default parameters
4. temlpate literals
5. for ... of loop
배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 함.
이렇게 말하니까 감이 잘 오지 않아서 여러 페이지들을 뒤적였는데, 정말 저 말 그대로였다. 배열이나 객체에 있는 값들을 개별 변수에 담을 수 있게 하는 표현식이었다.
나는 보통
let array = [1, 2, 3, 4];
let num1 = array[0];
let num2 = array[1];
.
.
num1; //1
num2; //2
이런 식으로 배열의 값들에 변수를 할당해 주었었는데,
구조 분해 할당은 이것을 더 간편하게 만들어 준다.
let array = [1, 2, 3, 4];
let [num1, num2, num3] = array;
num1; //1
num2; //2
let obj = {a: 'apple', b: 'banana'};
let {a, b} = obj;
a; //apple
b; //banana
let obj = {a: 'apple', b: 'banana'};
let {a = ap, b = bn} = obj;
ap; //apple
bn; //banana
let str = '안녕하세요';
let [a, , c, d, e, f];
a; //'안'
c; //'하'
f; //undefined
구조 분해 할당의 왼편엔 변수를, 오른편엔 배열이나 객체(스트링과 함수 포함)를 담는다.
나중에 나올 spread operator와 함께 쓸 수 있다.
let array = [1, 2, 3, 4, 5, 6];
let [1, 2, ...nums] = array;
nums; // [3, 4, 5, 6]
//함수의 매개변수도 이런 식으로 표현이 가능하다.
선언에서 분리한 할당도 가능하다.
let a, b;
[a, b] = [1, 2];
a; //1
b; //2
MDN 페이지
보통 스프레드 오퍼레이터라고 부른다. 나 혼자 부를 땐 쩜쩜쩜 구문이라고 한다. 왜냐하면 스프레드 오퍼레이터는 정말 쩜쩜쩜으로부터 시작하기 때문이다.
개발 언어가 아닌 보통의 이 쩜쩜쩜...은 국어 구문과 같이 할 말이 더 남았지만 말을 줄이는, 일종의 생략일 것이라고 추측할 것이다. 하고 싶은 말이 더 남아 있는, 무언가의 찝찝함(?)을 주는 점들.
나는 이 보편적인 추측이 개발 언어인 스프레드 오퍼레이터와도 흡사하다고 생각한다. 이것을 쓸 땐, 지정하지 않았던, 남아 있는 것들에 대한 것을 위해 쓰기 때문이다.
나는 보통 이것을 정확한 길이가 주어지지 않는 변수에 활용을 많이 한다.
//함수에서의 쓰임
function foo(x, y, z) { console.log(x, y, z)};
let args = [0, 1, 2];
foo(...args); //0, 1, 2
function foo(x, ...args) { console.log(x, ...args) };
foo(1, 2, 3, 4, 5); //1, 2, 3, 4, 5
function foo(x, y, z, a, b) { console.log(x, y, z, a, b) };
let args = [0, 1];
foo(1, ...args, 3, ...['apple']); // 1, 0, 1, 3, 'apple'
인수 목록의 모든 인수는 전개 구문 사용이 가능하고, 여러 번 사용이 가능하다.
살피다가 조금 놀란 것은 new를 사용할 때인데, 아주 편리하게 생겼다.
let nowtime = [2020, 4, 29];
let day = new Date(...nowtime); //Fri May 29 2020 00:00:00 GMT+0900 (대한민국 표준시)
//생성자 함수를 사용해서 스프레드 오퍼레이터를 쓰는 것도 가능하지만, 그것은 일반 함수를 쓸 때와 다름이 없는 것 같아서 생략한다.
조금 더 강력하다는 느낌을 받는데, 배열 메소드인 push나 splice, concat 같은 것을 더 간편하게, 메소드를 사용하지 않고 할 수 있기 때문이다.
//배열 리터럴
let animal = ['cat', 'dog'];
let arr = ['bear', ...animal, 'rabbit'];
arr; // ['bear', 'cat', 'dog', 'rabbit'];
//배열 복사
let animal = ['cat', 'dog'];
let sameAnimal = [...animal];
sameAnimal; // ['cat', 'dog'];
//배열 복사 같은 경우엔 1 레벨 깊이에서 효과적으로 작용
//배열 연결
animal = [...animal, ...arr];
arr; //['cat', 'dog', 'bear', 'cat', 'dog', 'rabbit'];
객체 병합이 조금 더 쉬워졌다. Object.assign()보다 더 짧고 간결하게 사용할 수 있지만, 이것을 대체하거나 흉내를 낼 수는 없다. 왜냐하면 assign은 할당하는 것이고, 전개 구문은 복사하는 것이기 때문.
let obj1 = {a: 'apple', b: '33번'};
let obj2 = {a: 'aoa', c: '멋있다'};
let cloneObj = { ...obj1, ...obj2 };
// { a: 'aoa', b: '33번', c: '멋있다' }
MDN 페이지
ES6에서는 '확인할 수 없는 크기의 인자를 받았을 때의 대처법'으로 rest parameters를 발표했다. 예전엔 argument가 있었지만, 그것은 유사 배열이기 때문에 배열 메소드를 사용할 수 없는 불편함이 있었는데, rest parameter는 array 인스턴스로, 배열 메소드 사용이 가능하다. 또, 아규먼츠는 받은 인자의 전부를 표했지만 rest parameters는 주어지지 않았던 대상만을 목표로 한다.
이래저래 아규먼츠보다 레스트 파라미터가 더 세련되어 보인다.
구문은 스프레드 오퍼레이터와 똑같이 쩜쩜쩜 변수를 사용하면 된다.
function foo(a, b, ...args) {
console.log(a, b, ...args);
}
foo(1, 2, 3, 4, 5, 6, 7); // 1, 2, [3, 4, 5, 6, 7]
//이런 식으로 배열에 찬 상태로 보여진다.
하나의 값만 있어도, 인수가 제공되지 않아도(비어 있는 배열) 배열로 표현이 되고, 배열이기 때문에 length를 사용하며 배열 메소드를 쓸 수 있다.
MDN 페이지
인수의 기본 값을 정해 준다. 인수에 아무런 값을 주지 않아도 default parameters를 사용하여 지정해 주고 함수를 호출하면, 지정한 값이 들어가게 된다.
function foo(sky = '파랗다') {
console.log('오늘 날씨는 ' + sky);
}
foo(); // 오늘 날씨는 파랗다
foo('어둡다'); //오늘 날씨는 어둡다
첫 번째 인수에만 줄 수 있는 것이 아니라, 어떤 인수든 가능하다.
function foo(sky, feel = '하얗다') {
console.log('오늘 날씨는 ' + sky + '그래서 기분이' + feel);
}
foo('파랗다'); // 오늘 날씨는 파랗다 그래서 기분이 하얗다
foo('파랗다', '우울하다'); //오늘 날씨는 파랗다 그래서 기분이 우울하다
스트링에 인자나 변수를 묶을 때 조금 더 편리한 문법이다. 백틱(`)을 사용하고 스트링이 아닌 것은 ${} 사이에 넣어 준다. 아주 편리하다. 아주 좋다. 굳굳.
let abc = '알파벳';
let kk = '!';
'나는 오늘 ' + abc + '를 배웠다' + kk
///////////
`나는 오늘 ${abc}를 배웠다 ${kk}`
MDN 페이지
드디어 올 것이 왔군요....!
for ... of 루프는 for문, for in문, 배열 메소드인 forEach와 같이 순환문이다.
for of문은 for문보다 간결하고, 객체를 위한 for in문보다 훨씬 바운더리가 넓으며, 배열 메소드가 아니다. 그렇기에 iterble한 객체들은 전부 for of문 사용이 가능한 것...! 아규먼츠 오브젝트도 for of문으로 활용 가능하다.
ES6를 통해 새롭게 선보인 Map, Set 등등도 for of로 루프가 가능하다.
그렇지만 문자열과 배열을 for of로 간결하게 사용할 수 있다는 점이 너무너무너무너무 매력적이다. DOM도 for of문에서는 돌아간다는 사실! 쓰는 방법은 for in 문과 똑같다.
for in문으로 배열을 돌리게 되면, 해당 값이 나오는 게 아닌 인덱스의 번호(스트링)로 나오게 되는데, for of문으로 배열을 돌리게 되면 해당 값이 나오게 된다.
for문과 for of문에 대해 효율성에 대해 많은 이야기가 오고 가는 걸 가끔 봤었던 것 같은데, 아직.. 배우는 단계인 나는 효율성에 대해서 깊은 이야기를 나눌 수 없는 상태이기 때문에... ES6가 만들어 준 for 형제들을 알차게 써 보고, 효율성에 대한 이야기는 다시 해 보고 싶다.
let str = '안녕하세요';
let arr = [1, 2, 3, 4, 5];
for( let value of str ) {
console.log(value);
} // 안, 녕, 하, 세, 요
for( let value of arr ) {
console.log(value);
}// 1, 2, 3, 4, 5
function foo(a) {
for(let value of arguments) {
console.log(value);
}
}
foo(1, 2, 3, 4, 5); // 1, 2, 3, 4, 5
``