[자바스크립트]

[JavaScript/DeepDive]12.함수(2)

ki7348 2021. 5. 13. 13:50
  • [12.5] 함수 호출
  • 함수는 함수를 가리키는 식별자와 한 쌍의 소괄호인 함수 호출 연산자로 호출한다.
    • 함수를 호출하면 현재의 실행 흐름을 중단하고 호출된 함수로 실행 흐름을 옮긴다.
      • 이때 매개변수에 인수가 순서대로 할당되고 함수 몸체의 문들이 실행되기 시작한다.
  • 매개변수와 인수
  • 함수를 실행하기 위해 필요한 값을 함수 외부에서 함수 내부로 전달할 필요가 있는 경우, 매개변수(인자)를 통해 인수를 전달한다.
    • 인수는 값으로 평가될 수 있는 표현식이어야 한다.
      • 인수는 함수를 호출할 때 지정하며, 개수와 타입에 제한이 없다.
        • function add(x, y) {
               return x + y;
          }
          // 함수 선언문
          var result = add(1, 2);
          // 함수 호출
          // 인수 1과 2가 매개변수 x와 y에 순서대로 할당되고 함수 몸체의 문들이 실행된다.
  • 매개변수는 함수를 정의할 때 선언하며, 함수 몸체 내부에서 변수와 동일하게 취급된다.
    • 즉, 함수가 호출되면 함수 몸체 내에서 암묵적으로 매개변수가 생성되고 일반 변수와 마찬가지로 undefined로 초기화된 이후 인수가 순서대로 할당된다.
      • 매개변수는 함수 몸체 내부에서만 참조할 수 있고 함수 몸체 외부에서는 참조할 수 없다.
        • 즉, 매개변수의 스코프(유효 범위)는 함수 내부다.
  • 함수를 호출할 때 매개변수의 개수만큼 인수를 전달하는 것이 일반적이지만 그렇지 않은 경우에도 에러가 발생하지는 않는다.
    • 인수가 부족해서 인수가 할당되지 않은 매개변수의 값은 undefined다.
  • 인수확인
  • function add(x, y) {
         return x + y;
    }
    console.log(add(2)); // NaN
    console.log(add('a', 'b')); // 'ab'
  • 이러한 상황이 발생한 이유는 다음과 같다.
    1.  자바스크립트 함수는 매개변수와 인수의 개수가 일치하는지 확인하지 않는다.
    2.  자바스크립트는 동적 타입 언어다. 따라서 자바스크립트 함수는 매개변수의 타입을 사전에 지정할 수 없다.
  • ES6에서 도입된 매개변수 기본값을 사용하면 함수 내에서 수행하던 인수 체크 및 초기화를 간소화할 수 있다.
    • 매개변수 기본값은 매개변수에 인수를 전달하지 않았을 경우와 undefined를 전달한 경우에만 유효하다.
      • function add( a = 0, b = 0, c = 0) {
             return a + b + c;
        }
        console.log(add(1, 2, 3)); // 6
        console.log(add(1, 2)); // 3
        console.log(add(1)); // 1
        console.log(add( )); // 0
  • 매개변수의 최대 개수
  • 함수의 매개변수는 코드를 이해하는 데 방해되는 요소이므로 이상적인 매개변수 개수는 0개이며 적을수록 좋다.
    • 이상적인 함수는 한 가지 일만 해야 하며 가급적 작게 만들어야 한다.
  • 주의할 점은 함수 외부에서 함수 내부로 전달한 객체를 함수 내부에서 변경하면 함수 외부의 객체가 변경되는 부수 효과가 발생한다는 것이다.
  • 반환문
  • 함수는 return 키워드와 표현식(반환값)으로 이뤄진 반환문을 사용해 실행 결과를 함수 외부로 반환(return)할 수 있다.
  • 반환문은 두 가지 역할을 한다.
    1.  반환문은 함수의 실행을 중단하고 함수 몸체를 빠져나간다. 반환문 이후에 다른 문이 존재하면 그 문은 실행되지 않고 무시된다.
    2.  반환문은 return 키워드 뒤에 오는 표현식을 평가해 반환한다. return 키워드 뒤에 반환값으로 사용할 표현식을 명시적으로 지정하지 않으면 undefined가 반환된다.
  • 반환문은 생략할 수 있다.
    • 이때 함수는 함수 몸체의 마지막 문까지 실행한 후 암묵적으로 undefined를 반환한다.
  • 반환문은 함수 몸체 내부에서만 사용할 수 있다.
    • 전역에서 반환문을 사용하면 문법 에러(SyntaxError: Illegal return statement)가 발생한다.

 

 

  • [12.6] 참조에 의한 전달과 외부 상태의 변경
  • function changeVal(primitive, obj) {
         primitive += 100;
         obj.name = 'Kim';
    }
    // 매개변수 primitive는 원시 값을 전달받고, 매개변수 obj는 객체를 전달받는다.

    var num = 100;
    var person = { name: 'Lee' };

    console.log(num); // 100
    console.log(person); // {name: "Lee"}
    // 외부 상태

    changeVal(num, person);
    // 원시 값은 값 자체가 복사되어 전달되고 객체는 참조 값이 복사되어 전달된다.

    console.log(num); // 100
    // 원시 값은 원본이 훼손되지 않는다.

    console.log(person); // {name: "Kim"}
    // 객체는 원본이 훼손된다.
  • changeVal 함수는 매개변수를 통해 전달받은 원시 타입 인수와 객체 타입 인수를 함수 몸체에서 변경한다.
    • 원시 타입 인수를 전달받은 매개변수 primitive의 경우, 원시 값은 변경 불가능한 값이므로 직접 변경할 수 없기 때문에 재할당을 통해 할당된 원시 값을 새로운 원시 값으로 교체했고, 객체 타입 인수를 전달받은 매개변수 obj의 경우, 객체는 변경 가능한 값이므로 직접 변경할 수 있기 대문에 재할당 없이 직접 할당된 객체를 변경했다.
    • 이때 원시 타입 인수는 값 자체가 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 그 값을 변경(재할당을 통한 교체)해도 원본은 훼손되지 않는다.
      • 어떠한 부수 효과도 발생하지 않는다.
    • 하지만 객체 타입 인수는 참조 값이 복사되어 매개변수에 전달되기 때문에 함수 몸체에서 참조 값을 통해 객체를 변경할 경우 원본이 훼손된다.
      • 부수 효과가 발생한다.