자바스크립트

Section 4. 자바스크립트 함수 더 알아보기

포칼이 2023. 3. 26. 23:43

I. 중첩된 함수

function outer () {
  const name = '바깥쪽'
  console.log(name, '함수');

  function inner () {
    const name = '안쪽'
    console.log(name, '함수');
  }
  inner();
}

outer(); 
//바깥쪽 함수
//안쪽 함수

inner 함수는 outer 함수 안에서만 존재한다. inner함수는 outer함수 밖에서 쓰일 일이 없는 함수인 것이다. 

outer() 함수를 실행해보면 예시와 같은 결과가 나오게 된다. 

function addMulSub (x, y) {
  const add = (a, b) => a + b;
  const sub = (a, b) => a - b;
  const mul = (a, b) => a * b;

  return sub(mul(add(x, y), y), y);
}

console.log(addMulSub(8, 3)); //30

같은 개념을 화살표 함수로 표현한 것이다.

 

II. 재귀 함수 recursive function

재귀 함수란 어떤 함수 안에서 해당 함수를 또 호출하는 것을 말한다. 즉, 자기 자신을 또 호출하는 것을 말한다. 

function upto5 (x) {
  console.log(x);
  if (x < 5) {
    upto5(x + 1);
  } else {
    console.log('- - -');
  };
}

upto5(1);
upto5(3);
upto5(7);

두번째 출력문을 보자.

우선 3이 찍힌다. 다음에 x가 5보다 작으면 자기자신 즉, upto(4)가 실행되게 된다. 그러면 다시 처음으로 돌아가서

4가 출력되고 다시 upto(5) 가 실행되고 5가 출력되고 이때  x < 5를 만족하지 않게 되어 else문을 실행하게 되어 ---가 실행되고 함수가 종료가 된다. 출력문은 다음과 같다. 

3

4

5

---

다음은 upto5(1)을 실행했을때 스택 영역에서 일어나는 일을 표현한 그림이다. 

이처럼 재귀 함수는 자기 자신을 반복적으로 호출하는 것이기 때문에 종료 조건을 잘못 쓰면 stack overflow라는 오류가 발생할 수도 있으니 조심해야 한다. 

 

III. 즉시 실행 함수 Immideately Invoked Function Expression or IIFE

지금은 많이 쓰이지 않는 함수이기 때문에 간단히 개념만 알고 넘어가겠다.

즉시 실행 함수의 특징은 다음과 같다.

  • 딱 한번만 사용될 함수일때 사용된다. 
  • 전역 변수들을 사용하지 않고, 복잡한 기능을 일회성으로 실행할 때 사용됨
  • 다른 코드들과의 변수명이나 상수명 충돌을 막기 위해 사용된다.
  • 오늘날에는 모듈의 사용으로 대체되었다. 
(function () {
  console.log('IIFE');
})();

IV. 불변성 immutability

let x = 1;
let y = {
  name: '홍길동',
  age: 15
}
let z = [1, 2, 3];

function changeValue (a, b, c) {
  a++;
  b.name = '전우치';
  b.age++;
  c[0]++;

  console.log(a, b, c);
}

changeValue(x, y, z); //2 {name: '전우치', age: 16} [2, 2, 3]

console.log(x, y, z); //1 {name: '전우치', age: 16} [2, 2, 3]

changeValue를 실행했을 때의 출력 값과 원래 값을 출력 했을 때의 값의 차이를 눈여겨 보자. 

원시타입은 변하지 않았다. 그 이유는 함수에서는 실제 값이 아니라 복사된 값이 들어갔기 때문이다. 

하지만 참조 타입인 배열과 객체는 변했다. 그 이유는 복사된 값도 같은 객체나 배열을 가리키기 때문이다.

좀더 자세히 설명하자면 배열과 객체도 함수에서 복사된 값이 들어 갔다. 여기서 복사된 값이란 바로 주소를 말한다. 

이제는 알겠지만 참조 타입은 주소가 가리키는 값을 변경하게 되면 그 주소를 가리키는 모든 것들이 모두 바뀐 값을 가지게 된다. 따라서 함수를 사용할때 객체나 배열은 이런 특징을 가지고 있다는 사실을 항상 명심하자. 

 

정리하면 다음과 같다. 

원시타입 : 인자로 들어간 함수 내에서의 변경에 영향 받지 않음.

참조 타입 : 인자로 들어간 함수 내에서 요소가 변하면 실제로도 변함.

 

결국에는 함수에 주어진 인자를 변경하는 것은 좋지 않다. 

이상적인 함수는 받은 값들만 처리하여 새 값을 반환하는 것이다. 

함수를 만들게 되면 꼭 이 점을 명심하자.