fffo

함수 본문

Programming/Javascript

함수

gggs 2021. 9. 27. 12:28

함수

  • 매개변수(parameter) : 함수 내부로 입력을 전달 받는 변수
  • 인수(argument) : 입력 값
  • 코드의 재사용 → 유지보수의 편의성, 코드의 신뢰성, 코드의 가동성

함수 리터럴

  • 함수는 객체 타입의 값이기 때문에 함수도 함수 리터럴로 생성 가능
  • 일반 객체와 함수 객체의 다른 점 → 함수는 호출 할 수 있음, 함수 객체 고유의 프로퍼티 가짐
  • 함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자. 생략 가능함

함수 정의

  • 함수 선언문, 함수 표현식, Function생성자 함수, 화살표 함수(ES6)를 통해 정의
  • 각각의 정의 방법은 미묘한 차이가 존재

함수 선언문

  • 함수 선언문은 표현식이 아닌 문
  • 함수 리터럴은 선언문일 수도, 표현식일 수도 있는 중의적 표현
  • 함수 선언문에서는 함수 객체를 가리키는 주소의 식별자가 없기 때문에 js엔진이 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성해 그곳에 함수 객체를 할당함
  • 결국 함수는 함수 이름으로 호출되는 것이 아닌 함수 객체를 가리키는 식별자로 호출됨
  • 결론적으로 js엔진은 함수 선언문을 함수 표현식으로 변환해 함수 객체를 생성한다 생각 할 수 있음. 정확하게 동일하게 동작하는 것은 아님

함수 표현식

  • 함수는 값의 성질을 갖는 객체 → 일급 객체. 함수를 값처럼 자유롭게 사용 할 수 있음
  • 함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것이 일바적

함수 생성과 함수 호이스팅

  • 함수 선언문은 런타임 이전에 평가되어 객체가 생성 되어 함수 호이스팅이 일어남
  • 함수 표현식은 할당되어지는 변수만 호이스팅되고 평가되는 함수 표현식은 런타임 때 평가됨
  • 함수를 호출하기 전에 선언해야 한다는 직관에 부합하려면 함수 선언문 대신 함수 표현식을 사용 권장

Fucntion 생성자 함수

  • Function 생성자 함수로의 함수 생성은 일반적이지 않고 바람직하지도 않음
  • 클로저를 생성하지 않는 등 선언문이나 표현식으로 생성한 함수와 다르게 동작함

화살표 함수

  • ES6에서 도입됨
  • 생성자 함수로 사용될 수 없음, 기존 함수와 this 바인딩 방식이 다름, prototype 프로퍼티가 없음, arguments 객체를 생성하지 않는 등 자세한 내용은 해당 챕터에서 다시 공부

함수 호출

매개변수와 인수

  • 함수 호출 시 함수 몸체 내에서 배개 변수와 생성되고, 일반 변수와 같이 undefined로 초기화 됨
  • 매개변수보다 적게 인수 전달 시 남은 매개 변수는 undefined로 초기화
  • 매개변수보다 많게 인수 전달 시 arguments 객체의 프로퍼티로 보관

인수 확인

  • 인수로 적절하지 않은 타입의 변수가 전달 되어도 js 문법상 런타임 이전에 에러를 띄울 수 없음 → 타입스크립트와 같은 정적 타입을 선언할 수 있는 js의 상위 확장을 도입
  • 인수가 전달 되지 않았을 때, 함수 몸체에 단축 평가를 통해 초기화 하거나 ES6 이후에 도입된 매개변수 기본값을 이용하면 기본 값 설정 가능
// 런타임 시 인수의 타입 체크
function add(x, y) {
    if (typeof x !== 'number' || typeof y !== 'number') {
        throw new TypeError('all argumnet must be number');
    }
    return x + y;
}

// 기본값 설정 (두 가지 방법을 사용했지만 실제 코드에선 한 가지로 통일 권장)
function add2(a,b,c = 0) {
    a = a || 0
    b = b || 0
    return a + b + c;
}

매개변수의 최대 개수

  • ECMAScript 사양에서 매개변수의 최대 개수를 명시하진 않음
  • 함수의 매개변수는 코드를 이해하는 데 방해 요소이므로 최대한 적게 유지하는 것을 권장
  • 이상적인 함수는 한 가지 일을 해야 하며 가급적 작게 만들어야 함
  • 매개변수가 3개 초과 시 객체를 인수로 전달 권장 → 객체의 side effect 주의

반환문

  • 함수 호출은 표현식, return 키워드가 반환한 표현식의 평가 결과가 값으로 평가됨
  • 반환문을 명시적으로 지정하지 않을 시 undefined 반환
  • return 키워드와 반환값으로 사용될 표현식 사이에 개행이 있으면 세미콜론 자동 삽입 기능에 의해 undefined가 반환, 아래 표현식 무시됨

참조에 의한 전달과 외부 상태 변경

  • 객체를 인수로 전달 시 함수 내부에서 객체 변경 시 원본 객체도 변경됨
  • 함수가 외부 상태를 변화 시키면 상태 변화를 추적하기 어렵기 때문에 코드의 복잡성을 증가 시키고 가독성을 해침
  • 객체 변경 추적을 위한 옵저버 패턴 사용, 불변 객체 이용 등 대안이 필요
  • 순수 함수 : 외부 상태를 변경 하지 않고 의존 하지 않는 함수
  • 순수 함수를 통해 side effect를 최대한 줄여 안정성을 높이는 프로그래밍 패러다임을 함수형 프로그래밍이라 부름

다양한 함수의 형태

즉시 실행 함수(IIFE, Immediately Invoked Function Expression)

  • 함수 정의와 동시에 즉시 호출되는 함수
  • 한 번만 호출되며 다시 호출할 수 없음
  • 반드시 그룹 연산자(괄호)로 감싸야 함
  • 그룹 연산자의 피연산자는 값으로 평가됨 → 함수를 그룹 연산자로 감싸면 함수 리터럴로 평가되어 함수 객체가 됨
  • 즉시 실행 함수 내에 코드를 모아 두면 변수나 함수 이름의 충돌을 방지할 수도 있음

재귀 함수, 중첩 함수

  • 재귀 함수 : 함수 내에서 함수 객체를 가리키는 식별자 혹은 함수 이름으로 자기 자신을 호출
  • 중첩 함수(내부 함수) : 함수 내부에 정의된 함수. 일반적으로 중첩 함수는 자신을 포함하는 외부 함수를 돕는 핼퍼 함수(helper function)의 역할을 함
  • ES6 이후 함수 정의는 문이 위치할 수 있는 문맥이면 어디든지 가능 → if문, for문 등 코드 블록 내에서 정의 가능하지만 호이스팅으로 인한 혼란 유래하므로 지양

콜백 함수

  • 콜백 함수 : 함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수
  • 고차 함수 : 매개 변수를 통해 함수의 외부에서 콜백 함수를 전달 받은 함수
  • 콜백 함수가 고차 함수 내에서만 호출되면 익명 함수 리터럴로 정의해 바로 전달하는 것이 일반적 → 고차 함수가 호출될 때마다 콜백 함수가 생성됨
  • 콜백 함수가 다른 곳에서도 호출될 필요가 있거나 고차 함수가 자주 호출된다면 함수 외부에 콜백 함수를 정의 후 함수 참조를 고차 함수에 전달하는 것이 효율적임

순수 함수와 비순수 함수

  • 부수 효과(side effect)가 없는 함수 → 순수 함수
  • 순수 함수는 동일한 인수 전달 시 항상 동일한 값을 반환함 → 오직 인수에만 의존해 반환 값 생성
  • 함수형 프로그래밍 :
    • 부수 효과 최소화, 불변성 지향 프로그래밍 패러다임
    • 로직 내에 존재하는 조건문, 반복문을 제거해 복잡성 해결
    • 변수 사용 억제, 생명주기 최소화로 상태 변경을 피해 오류 최소화 목표
    • js는 멀티 패러다임 언어, 함수형 프로그래밍 또한 적극 활용 중

'Programming > Javascript' 카테고리의 다른 글

스코프  (0) 2021.09.28
js 복습 - 깊은복사, 생성자, Date  (0) 2021.09.27
원시 값과 객체의 비교  (0) 2021.09.26
객체 리터럴  (0) 2021.09.25
타입 변환과 단축 평가  (0) 2021.09.24
Comments