본문 바로가기

Language/JS

매개변수 패턴

0. 기본형

function sum(a, b) { // 여기는 인수를 받는 매개체 매개변수
  return a + b;
}

console.log(sum(1, 2)); // 여기가 들어온 값 인수

인수, 매개변수 두 용어를 헷갈렸었는데, 

인수는 함수가 호출되어 실제 들어오는 값을 뜻하고, 

매개변수는 함수 선언문에 적히는 인수를 받는 매개체를 뜻한다.

1. 기본값

위의 함수에서 만약에 사용자가 sum 함수를 호출하고 인수를 하나만 쓴 경우 어떻게 될까?

console.log(sum(7)); // 7과 undefined를 더 해서 not a number

두 번째 인수로는 undefined가 들어가서 7 + undefined가 되어 NaN이 출력될 것이다. 

이를 방지하기 위해서 매개변수에 조치를 취할 수 있다. '매개변수 = 기본값'의 형태를 통해 혹시 매개변수로 값이 들어오지 않는다면 대신 쓰일 기본값을 설정할 수 있다. 

function sum(a, b = 1) {
  return a + b;
}


console.log(sum(1,2)); 	// 이건 정상적으로 3이 출력됨.
console.log(sum(7));	// output : 8

2. 구조분해 할당

(1) 객체

const user = {
  name: "heropy",
  age: 85,
  email: "dfmldfmkl",
};

function getName1(user) {
  return user.name;
}

function getName2(user) {
  const { name } = user;
  return name;
}

function getName3({ name }) {
  return name;
}

function getEmail({ email = "이메일이 없습니다." }) {
  return email;
}
console.log(getName1(user));
console.log(getName2(user));
console.log(getName3(user));

console.log(getEmail(user));

출력 내용

getName1 ~3은 모두 같은 로직이다.

1번은 노말하게 객체 인수를 받아서 해당 인수 중 name이라는 멤버에 접근했다. 

2번은 객체인수를 받아서 구조 분해를 통해 name이란 key의 value를 뽑아내어 사용했다. 

 

3번이 우리가 배울 내용인데, 

이 처럼 매개변수 공간에서 바로 구조분해 할당을 하여 쓸 수 가있다. 

 

4번은 구조분해 할당 객체에서 배웠듯이 만약 해당 key가 객체안에 없다면 해당 key의 value로는 대체해서 쓰일 내용을 적어주는 문법이다.  만약 email이란 멤버가 객체안에 없는데, email을 return하면 "이메일이 없습니다가 대체 출력될 것이다."  하지만 위의 user 객체에는 email 이란 key가 있어서 해당 key의 value가 출력되었다.

(2) 배열

// (2) 배열
const fruits = ["Apple", "Banana", "Cherry"];
const number = [1, 2, 3, 4, 5, 6, 7, 8, 9];

function getSecoendItem([, b]) {
  return b;
}

console.log(getSecoendItem(fruits));
console.log(getSecoendItem(number));

배열 또한 매개 변수 부분에서 바로 구조분해가 가능하다. 알다시피 배열 구조분해는 객체랑 다르게 변수가 쓰인 index로서 원소를 구분한다. (객체는 변수의 이름이 key 이름이랑 동일해야 한다. 따라서 해당 변수 이름으로 대응하는 value 값을 찾아 뽑아낸다.) 

 

위의 예시에서는 무조건 배열의 두번째 값만 뽑아내는 구조분해를 보여줬다.

3. 나머지 매개변수 

Java에서는 오버로딩을 통해 같은 이름의 함수에 관해서 들어오는 인수의 갯수나 타입이 다를 때, 대응하는 로직을 다르게 해줄 수 있었다. 즉 인수의 갯수나 타입이 다르면 같은 이름의 함수를 중복해서 쓸 수 있었던 것이다. 

 

JS에서 같은 이름의 함수에 들어오는 인수의 값이 제각각이면 어떻게 대응할까? 

여기도 구조분해 할당과 연관되는 내용인데 ...rest "전개 연산자"를 사용한다. 

// (3) 나머지 매개변수
function sum1(...rest) {
  // 전개 연산자로 쓰여진 매개변수는 인수들을 받아서 배열로 저장한다.
  console.log(rest);
}

console.log(sum1(1, 2));
console.log(sum1(1, 2, 3, 4));
console.log(sum1(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

전개 연산자로 쓰인 매개변수는 인수들을 받아서 배열로서 저장한다. 그래서 출력결과를 보면 배열 형태로 되어 있다.

undefined는 신경쓰지 말자. 우리가 sum1이란 함수에 반환 값을 따로 지정해주지 않았기 때문에 저렇게 나오는 것이다. 

return 값을 따로 설정해주지 않으면 반환 시 undefined가 나오게 된다. 

 

만약 매개변수와 전개 연산자 매개변수가 혼재되어 있으면, 어떻게 인수가 할당 될까? 

일단 차례대로 매개변수에게 값이 들어가고 그 나머지를 전개 연산자가 가져가서 배열로서 저장한다. 

function sum2(a, b, ...rest) {
  
  console.log(rest);
  console.log(arguments);
 
  return rest.reduce(function (acc, cur) {
    return acc + cur;
  }, 0);
}


console.log(sum2(1, 2));
console.log(sum2(1, 2, 3, 4));
console.log(sum2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));

첫 번째 꺼에는 1,2가 모두 a,b에 다 들어갔기에 rest 연산자에는 아무것도 안 들어간 것을 확인할 수 있다. 

나머지 2개의 출력도 a,b에게 할당된 것은 빠진 모습이다. 

이렇게는 사용할 수 없다. 전개 연산자 매개변수는 무조건 매개변수들의 맨 마지막에 있어야 한다. 

 

**arguments에 대하여**

arguments는 따로 기입하지 않아도 해당 함수로 들어오는 모든 인수의 값을 가지고 있는 객체이다. 

key값이 인덱스이고, value로 인수들이 차례대로 들어간 형태로, 배열 데이터와 형태가 비슷하다. 

arguments 출력 형태를 보면 이해가 될 것이다. 

함수 내에서는 arguments를 따로 선언하지 않아도 쓸 수 있다. 

4. 새롭게 알게 된 것

배열의 내장함수 reduce에 대해서 알게 되었다. 

reduce() 매소드는 4개의 인자를 필요로 하는 위의 call back 함수를 실행한다. 해당 call back 함수를 reducer라고 한다. 

(call-back이란, 어떤 코드에 인수로 들어가는 실행 가능한 코드를 말한다.)

reducer 함수는 배열의 원소 수만큼 반복되며, 배열의 원소들을 순회한다.  

먼저 함수의 첫번째 인자 : acc는 누적의 의미를 가지고, 첫 번째 실행일시 초기값, 그 이후부터는 이전 실행의 반환값을 저장한다. 

두 번째 인자, cur는 current의 의미로 현재 순회 중인 원소를 의미한다. 초기값을 따로 지정해주지 않으면 index: 1부터 순회한다.(index: 0번이 초기값이 되므로), 초기값을 따로 지정하면 index: 0 부터 순회한다.

 

세 번째로 함수 뒤에 적혀 있는 것은 초기값이다. 맨 처음 acc에 들어가는 값이다. 

 

쓰이진 않았지만, 세번째 인자로 currentIdx 가 있다. 이건 선택사항이다. 해당 인자는 현재 순회 중인 원소의 index 값을 인수로 받는다. 

 

여기서는 이전 실행의 반환 값을 현재 순회 중인 원소와 계속 더하는 반복을 했다. 

 

5. 스스로 해보기

(1) 객체를 매개변수 레벨에서 바로 구조분해 할당 받아서 써보기. 기본값도 써보기

(2) 배열을 매개변수 레벨에서 바로 구조분해 할당 받아서 써보기

(3) rest 변수를 이용하여 값 계산 해보기 

반환값은 그냥 놔두면 출력 안된다. 출력 함수를 써야지 출력된다! 

'Language > JS' 카테고리의 다른 글

즉시 실행 함수 (IIFE)  (0) 2023.04.20
화살표 함수  (0) 2023.04.19
함수의 반환과 종료  (0) 2023.04.18
함수 선언문과 함수 표현 식의 차이 그리고 호이스팅  (0) 2023.04.18
HTML에서 JavaScript 쓰기  (0) 2023.04.17