본문 바로가기

프로그래밍/js

ES6 lesson 4. 확장 파라미터 핸들링

2023.03.26

자바스크립트 스터디 10회차

공부 사이트: https://poiemaweb.com/

 

4. 확장 파라미터 핸들링

1) 매개변수 기본값

함수 호출 시 매개변수 개수만큼 인수를 전달하지 않아도 에러가 발생하진 않는다.

함수가 매개변수의 개수와 인수 개수를 체크하지 않기 때문인데, 인수가 부족한 경우 매개변수의 값은 undefined가 된다.

그래서 매개변수의 개수에 맞게 인수가 전달되었는지를 확인하는 로직이 필요했었다.

그러나 ES6부터는 인수 체크 및 초기화를 간소화할 수 있게 되었다.

// 매개변수 x와 y를 0으로 초기화 (기본값)
function sum(x=0,y=0){
	return x+y;
}

console.log(sum(1));   //1
console.log(sum(1,2,));   //3

 

 

2) Rest 파라미터

① 기본 문법

Rest 파라미터는 함수에 전달된 인수의 목록을 배열로서 전달받는다. 매개변수 이름 앞에 세개의 점을 붙여서 사용한다.

function func(...rest) {
    console.log(Array.isArray(rest));   //true
    console.log(rest);
}

func(1,2,3,4,5);

함수에 전달된 인수들은 순차적으로 파라미터 , Rest 파라미터에 할당되게 된다.

먼저 선언된 파라미터에 할당된 인수를 제외한, 나머지 인수들이 모두 배열에 담겨서 할당된다. 

Rest 파라미터를 사용할 경우, 반드시 마지막 파라미터로서 위치해야 함.

또한 length 프로퍼티에 영향을 주지 않는다. ( Rest 파라미터는 매개변수 개수로서 카운팅되지 않음을 의미 )

console.log('[*] func1');
function func1(param, ...rest) {
  console.log(param); 
  console.log(rest);  
}

func1(1, 2, 3, 4, 5);

console.log('\n[*] func2');
function func2(param1, param2, ...rest) {
  console.log(param1); 
  console.log(param2); 
  console.log(rest);   
}

func2(1, 2, 3, 4, 5);

 

② arguments 객체와 rest 파라미터

ES5에서 인자의 개수를 사전에 알 수 없는 가변 인자 암수는 arguments 객체를 통해 인수를 확인했다.

#arguments 객체: 함수 호출 시 전달된 인수들의 정보를 담고있는 순회가능한 유사 배열 객체. 

그러나 유사 배열 객체이므로, 배열 메소드를 사용하려면 Function.prototype.call을 사용해야 하는 번거로움이 있었다.

#call(this, arg1, arg2 ...): 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출

ES6부터는 rest 파라미터를 사용하여 가변 인자 목록을 배열로서 받을 수 있기에, 해당 번거로움을 피할 수 있다.

 

 

 

3) Spread 문법

해당 문법을 사용하면 객체 또는 배열을 펼쳐볼 수 있다. (...)

단, 해당 문법의 대상은 반복 가능(iterable)해야 한다.

console.log(...[1,2,3]); 
console.log(...'hello');
console.log(...new Map([['a','1'],['b','2']]));
console.log(...new Set([1,2,3]));

// console.log(...{a:1, b:2});   반복 가능하지 않은 일반 객체. TypeError

 

언제 사용하는가?

 

① 배열을 분해해서 각 요소를 함수의 파라미터에 전달하고 싶을 경우

- 원래는 Function.prototype.apply를 사용

- ES6의 Spread 문법을 사용하여 전달하면, 배열의 요소를 분해하여 순차적으로 파라미터에 할당할 수 있음.

- Spread 문법을 사용하는 것이 더 간단하다.

function func(x,y,z){
	console.log(x);
	console.log(y);
	console.log(z);
}

const arr = [1, 2, 3];

console.log('[*] apply 사용');
func.apply(null, arr);
console.log('[*] Spread 문법 사용');
func(...arr);

 

② 배열에서 사용 (간결, 가독성)

a. 기존 배열의 요소를 새로운 배열 요소의 일부로 만들고 싶은 경우

- 원래는 concat 메소드를 사용

- ES6의 Spread 문법을 사용하면 배열 리터럴만으로 가능

// ES5
var arr1 = [1,2,3];
console.log(arr1.concat([4,5,6]));

//ES6
const arr2 = [1,2,3];
console.log([...arr, 4, 5, 6]);

 

b. 기존 배열에 다른 배열의 개별 요소를 넣고 싶은 경우

- 원래 apply, push 함께 사용

- ES6의 Spread 문법을 사용하면 간단히 가능

// ES5
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];

// Array.prototype.push.apply() 통해 두 개의 배열을 합칠 수 있음
Array.prototype.push.apply(arr1, arr2);

console.log(arr1);
// ES6
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];

// arr1.push(4,5,6) 과 같은 의미
arr1.push(...arr2);

console.log(arr1);

※ push.apply : 첫 번째 인자는 this, 두 번째 인자는 배열을 받은 후 push 함수 수행

 

 

c. 기존 배열에 다른 배열의 개별 요소를 삽입하고 싶은 경우

- 원래 apply, splice 함께 사용

- ES6의 Spread 문법을 사용하면 간단히 가능

// ES5
var arr1 = [1, 2, 3, 6];
var arr2 = [4, 5];

// [3, 0].concat(arr2): [3, 0, 4, 5]
// apply에서 arr1은 this, 결국 splice를 호출하는 건 arr1
// arr1.splice(3, 0, 4, 5): arr1[3]부터 0개 요소 제거하고 그 자리에 새로운 요소 추가
Array.prototype.splice.apply(arr1, [3, 0].concat(arr2));

console.log(arr1);
// ES6
const arr1 = [1, 2, 3, 6];
const arr2 = [4, 5];

// ...arr2는 [4, 5]을 개별 요소로 분리
arr1.splice(3, 0, ...arr2); 

console.log(arr1);

 

d. 기존 배열을 복사하고 싶은 경우

- 원래는 slice 사용

- ES6의 Spread 문법을 사용하면 간단히 가능

// ES5
var arr  = [1, 2, 3];
var copy = arr.slice();

console.log(copy);
// ES6
const arr = [1,2,3];
const copy = [...arr];

console.log(copy);

물론 여기서 이루어지는 복사는 "얕은 복사(shallow copy)" 이다.

 

e. 유사 배열 객체를 배열로 변환하고 싶을 때

// 유사 배열인 HTMLCollection을 배열로 변환
const htmlCollection = document.getElementsByTagName('li');

const newArray = [...htmlCollection];

'프로그래밍 > js' 카테고리의 다른 글

ES6 lessons. 6 Destructuring  (0) 2023.03.28
ES6 lessons 5. 향상된 객체 리터럴  (0) 2023.03.26
ES6 lessons 3. 화살표 함수  (0) 2023.03.26
ES6 lesson 1 ~ 2  (0) 2023.03.26
lessons 36. SPA & Routing  (0) 2023.03.26