함수

heejung·2022년 3월 20일
0

deep dive

목록 보기
10/20
post-custom-banner
  • 일급 객체 (값의 성질을 갖는 객체)
  • 일반 객체와 달리 호출 가능
  • 함수 객체만의 고유한 프로퍼티를 가짐
// 함수 정의
function add(x, y) { // 매개변수(입력을 전달받는 변수)
  return x + y; // 반환값
}

// 함수 호출
add(2, 5); // 인수(입력) => 매개변수로 전달

함수 사용하는 이유


  • 동일한 작업을 반복 수행해야할 때 코드 재사용
  • 유지보수의 편의성
  • 코드의 신뢰성을 높임

함수 리터럴


  • function 키워드, 함수명, 매개변수, 함수 몸체로 구성
  • 표현식인 문 => 값으로 객체를 생성
var f = function add(x, y) { // 함수명, 매개변수
  // 함수 몸체
  return x + y;
};
 설명
함수명- 식별자 네이밍 규칙 준수해야함
- 함수 몸체 내에서만 참조 가능
- 생략 가능 (함수명 있으면 기명 함수, 없으면 무명/익명 함수)
매개변수- 각 매개변수에 함수 호출 시 지정한 인수 순서대로 할당됨
- 함수 몸체 내에서 변수로 취급 => 식별자 네이밍 규칙 준수해야함
함수 몸체- 함수 호출에 의해 실행됨

함수 정의


  • 인수를 전달받을 매개변수, 실행할 문, 반환 값 지정
  • 자바스크립트 엔진이 함수명과 동일한 식별자 생성 => 식별자로 호출

함수 선언문

  • 함수명 생략 불가
  • 표현식이 아닌 문 => 값 (피연산자) 으로 사용될 수 없음
function add(x, y) {
  return x + y;
}

함수 표현식

  • 함수 리터럴 (표현식인 문) => 변수에 할당하는 방식
  • 함수명 생략 가능 (일반적으로 생략)
// 기명 함수 표현식
var add = function add(x, y) {
  return x + y;
}

// 익명 함수 표현식
var add = function(x, y) {
  return x + y;
}

함수 생성 시점과 함수 호이스팅

함수 선언문

  • 함수 호이스팅이 일어남
  • 런타임 이전에 함수 객체가 생성되고 할당됨
  • 함수 선언문 이전에 함수 참조/호출 가능

함수 표현식

  • 변수 호이스팅이 일어남
  • 런타임 이전에 변수가 생성되고 undefined 가 할당됨
  • 함수 표현식 이전에 함수 호출/참조 시 undefined로 평가 => 타입 에러 발생

Function 생성자 함수

  • new 연산자와 함께 호출 => 함수 객체 생성해 반환
    (new 연산자 없이 호출해도 결과 동일)
  • 생성된 함수가 클로저를 생성하지 않음
  • 바람직한 함수 생성 방식 X
var add = new Function('x', 'y', 'return x + y');

화살표 함수

  • ES6에서 도입됨
  • 항상 익명 함수로 정의함
  • 기존 함수와 this 바인딩 방식이 다름
  • prototype 프로퍼티 X
  • arguments 객체 생성 X
const add = (x, y) => x + y;

함수 호출


매개변수와 인수

  • 함수 외부에서 함수 실행을 위해 필요한 값을 함수 내부로 전달할 때 사용
  • 인수 개수, 타입에 제한 X
  • 매개변수 => 함수 몸체 내부에서만 참조 가능

함수가 호출되면 함수 몸체 내에서 암묵적으로 매개변수가 생성되고 일반 변수처럼 undefined 로 초기화된 후 인수가 순서대로 할당된다.
함수는 매개변수와 인수의 개수가 일치하는지 체크하지 않으므로, 인수가 부족해서 인수가 할당되지 않은 매개변수의 값은 undefined 가 되고, 에러가 발생하지 않는다.
매개변수보다 인수가 더 많은 경우에는 초과된 인수는 암묵적으로 arguments 객체의 프로퍼티로 보관된다.


인수 확인

자바스크립트는 함수의 매개변수와 인수의 개수가 일치하는지 확인하지 않고, 동적 타입 언어이기 때문에 매개변수의 타입을 사전에 지정할 수 없다.
따라서 함수를 정의할 때 적절한 인수가 전달되었는지 확인할 필요가 있다.

  • 함수 내부에서 인수 확인하는 코드 구현
  • 타입스크립트 (정적 타입을 선호할 수 있음) 사용

매개변수의 최대 개수

  • 명시적인 제한은 없음
  • 매개변수의 개수는 적을수록 좋음 (함수는 한 가지 일만 해야하며 가급적 작게 만들어야함)
  • 최대 3개 이상 넘지 않는 것을 권장
  • 그 이상이 필요하면 객체로 전달하는 것이 좋음

반환문

  • return 키워드로 함수 실행 결과를 외부로 반환
  • 함수 실행 중단하고 함수 몸체를 빠져나감
  • 생략 시 암묵적으로 undefined 반환

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


  • 원시 타입 인수 => 값 자체가 복사되어 매개변수에 전달
  • 객체 타입 인수 => 참조 값이 복사되어 매개변수에 전달 (원본 변경 가능)

객체 변경 추적 방법

  • 옵저버(Observer) 패턴 사용 => 객체 참조 공유하는 모든 이들에게 변경 사실 통지
  • 불변 객체로 만들어 사용 => 방어적 복사 (깊은 복사)

다양한 함수의 형태


즉시 실행 함수

  • 함수 정의와 동시에 즉시 호출
  • 단 한 번만 호출됨
  • 일반적으로 익명 함수 사용
// 그룹 연산자 사용
(function() {
  var a = 3;
  var b = 5;
  return a * b;
}());

재귀 함수

  • 자기 자신을 호출하는 함수
  • 반복되는 처리를 위해 사용
  • 무한 재귀 호출을 멈출 탈출 조건이 반드시 필요
// 반복문 사용
function countdown(n) {
  for (var i = n; i >= 0; i--) {
    console.log(i);
  }
}

countdown(10);
// 재귀함수 사용
function countdown(n) {
  if (n < 0) return;
  console.log(n);
  countdown(n - 1); // 재귀 호출
}

countdown(10);

중첩 함수 (내부 함수)

  • 함수 내부에 정의된 함수
  • 외부 함수 내부에서만 호출 가능
  • 외부 함수를 돕는 헬퍼 함수의 역할
function outer() {
  var x = 1;
  
  // 중첩 함수
  function inner() {
    var y = 2;
    // 외부 함수의 변수 참조 가능
    console.log(x + y); // 3
  }
  
  inner();
}

outer();

콜백 함수

  • 매개변수를 통해 다른 함수의 내부로 전달되는 함수
  • 고차 함수 : 콜백 함수를 전달받은 함수
  • 고차 함수가 콜백 함수의 호출 시점을 결정
  • 비동기 처리 (이벤트 처리, Ajax 통신, 타이머 함수 등), 배열 고차 함수에 활용
// myButton 클릭 시 콜백 함수 실행
document.getElementById('myButton').addEventListener('click', function() {
  console.log('button clicked!');
});

// 1초 후에 메시지 출력
setTimeout(function() {
  console.log('1초 경과');
}, 1000);
// 배열 고차 함수 map
var res = [1, 2, 3].map(function(item) {
  return item * 2;
});

console.log(res); // [2, 4, 6]

순수 함수와 비순수 함수

순수 함수

  • 외부 상태에 의존, 변경X (=부수 효과X)
  • 매개변수를 통해 전달된 인수에게만 의존해 값을 생성
  • 동일한 인수가 전달되면 언제나 동일한 값을 반환
  • 인수의 불변성을 유지
var count = 0;

// 순수 함수
function increase(n) {
  return ++n;
}

// 순수 함수 반환값을 변수에 재할당 => 상태를 변경
count = increase(count); 
console.log(count); // 1

count = increase(count); 
console.log(count); // 2

비순수 함수

  • 외부 상태 의존, 변경O (=부수 효과O)
  • 외부 상태에 따라 반환값 달라짐
  • 상태 변화를 추적하기 어려움
var count = 0;

// 비순수 함수
function increase() {
  return ++count; // 외부 상태 직접 참조 => 외부 상태 변경
}

increase(); 
console.log(count); // 1

increase(); 
console.log(count); // 2

함수형 프로그래밍

  • 비순수 함수를 최대한 줄여 부수 효과를 억제
  • 순수 함수와 보조 함수의 조합을 통한 불변성을 지향
  • 조건문과 반복문을 제거해 복잡성을 해결
  • 변수 사용 억제, 생명주기 최소화
profile
프론트엔드 공부 기록
post-custom-banner

0개의 댓글