[JS] 함수 - Function

Im-possible·2025년 4월 3일

함수

- 명령어의 묶음으로 특정 기능을 재사용하고 싶을 때 작성
- 두번 이상 사용할 일이 있다면 함수로 만드는 것이 좋다.
- 함수를 선언해도 호출하지 않으면 실행하지 않는다.
- 매개변수는 필수가 아니다.
  • 자바스크립트의 함수는 일급 객체이다. 함수 == (호출 + 객체)
// 형식
function 함수명 (매개변수) {
  실행할 구문;
  ...
  return 반환값
}

// 함수 호출
const result = 함수명(인자값)

일급 객체

- 변수, 배열 엘리먼트, 다른 객체의 프로퍼티에 할당될 수 있다
- 함수의 인자로 전달될 수 있다
- 함수의 결과 값으로 반환될 수 있다
- 리터럴로 생성될 수 있다
- 동적으로 생성된 프로퍼티를 가질 수 있다
- 콜백 함수, 고차 함수, 클로저 가능

콜백 함수

- 매개변수로 함수 객체를 전달해서 호출 함수 내에서 매개변수 함수를 실행하는 것
- 특정한 상황이 되거나(이벤트 발생) 지정한 시간이 흐르면(timeout) 또는 특정 작업의 수행이 끝나면 호출하도록 지정한 함수
- 익명함수 사용
function sayHello(name, callback){
  const words = '안녕하세요 저는 ' + name + ' 입니다';
  
  callback(words);
}

sayHello("이름", function (name){
  console.log(name);
});

고차 함수

- 함수를 인자로 받거나 함수를 반환하는 함수
- `.map()`, `.filter()` 등
- Currying(함수를 반환), Partial application(함수를 인자로 받고 함수를 반환)

클로저

- 내부 함수가 외부 함수의 스코프에 접근할 수 있게 하며 외부 함수의 실행이 끝난 후에도 외부 함수의 변수에 접근할 수 있게 한다

함수 생성

선언문

- function 키워드로 시작하는 함수 정의
- 함수 이름: 생략 가능(익명함수, 기명함수)
- 매개변수 목록: 쉼표로 구분, 생략 가능, 괄호 필수
- 함구 본문: 생략 가능, 중괄호 필수
// 기명함수
function sayHello () {
  console.log('안녕 Function!');
}

// 함수 호출
sayHello();

표현식

- 함수 정의를 변수에 할당하여 변수명을 함수명처럼 사용
- 주로 익명함수 사용

익명함수

- 변수에 익명함수 지정
const add = function(x, y){
  const result = x + y;
  return result;
}
console.log(add(10, 20));

기명 함수

- 변수에 기명함수 지정
- 변수명을 함수명처럼 사용
- 함수명을 통한 접근은 해당 함수 내부에서만 사용 가능(재귀함수)
const add = function sum(x, y){
  const result = x + y;
  return result;
}

console.log(add(10, 20));
console.log(sum(10, 20)); // 에러 발생

// 함수명을 통한 접근 예시 (재귀함수)
const f = function factorial(n){
	if (n===1) return 1;
  return n * factorial(n-1);
};

console.log(f(5));
console.log(factorial(5)); // 에러 발생

new Function 생성자 함수

- `new`를 붙아고 대문자로 시작
- `functionBody`를 생성할 때 매개변수 괄호의 맨 끝에 적는다
- 가독성이 떨어져서 잘 사용 안함
const add = new Function('x', 'y', 'const result = x + y; return result;')

console.log(add(10, 20));

화살표 함수

- 함수 표현식의 대안으로 익명함수로만 정의 가능
- 실행할 코드가 하나만 있다면 함수 본문의 중괄호 생략 가능
- 매개변수가 하나만 있다면 매개변수의 괄호 생략 가능
- 매개변수가 없는 경우 빈 괄호 필수
- 선언문 방식에는 사용 불가능(익명함수로만 정의 가능하기 때문에)
// 기존 함수
let add10 = function(x) {
  return x + 10;
};

// 화살표 함수
add10 = x => {
  return x + 10;
}

// 화살표 함수 축약
add10 = x => x + 10;

참조 타입

Call by Value - 값에 의한 호출

- 기본 데이터 타입은 실제 데이터를 저장하고 다룸
- 값을 복사하여 전달하기 때문에 함수 안에서 변경한 값이 함수 밖에서는 유지되지 않음

Call by Reference - 참조에 의한 호출

- 참조형 데이터 타입은 실제 데이터가 있는 위치의 주소를 저장하고 다룸
- 주소를 전달하기 때문에 함수 안에서 변경한 값이 함수 밖에서도 유지됨
function add10(data1, data2) {
  data1 += 10;
  data2[0] += 10;
  console.log('함수 내부', data1, data2[0]); // 90 90
}

let d1 = 80; // 원시타입 - number
let d2 = [ 80 ]; // 참조 타입 - array(object)

console.log('함수 호출 이전', d1, d2[0]); // 80 80

add10(d1, d2);

console.log('함수 호출 이후', d1, d2[0]); // 80 90

매개변수와 인자의 수

- 자바스크립트는 약형언어이기 때문에 매개변수와 함수 호출에 사용되는 인자의 수가 달라도 에러가 발생하지 않는다.
- 

매개변수 > 인자

- 부족한 인자에 대한 매개변수에는 undefine가 지정
function add(x, y, z)
  console.log(z); // undefined 출력
  return x + y;
}
console.log(add(3, 4)); // 7 출력

매개변수 < 인자

- 남는 인자에 대해서는 처리할 매개변수가 없기 때문에 무시됨
function add(x, y)
  return x + y;
}
console.log(add(3, 4, 5)); // 7 출력

암묵적 매개변수

- 모든 함우세어 명시적으로 선언하지 않고 암묵적으로 사용할 수 있는 매개변수
- arguments, this

arguments

- 함수 내에서 arguments 변수로 접근 가능
- 유사 배열 객체로 length 속성과 indexfh rkr dlswkdp wjqrms rksmd
- arguments 대신 나머지 매개변수(...) 사용 권장
function fn(n1, n2){
  let sum = 0;
  for(let i=0; i<arguments.length; i++){
    sum += arguments[i];
  }
  console.log('합계', sum);
}

나머지 매개변수(...)

function fn(n1=0, n2=0, ...nums){
  var sum = n1 + n2;
  for(var i=0; i<nums.length; i++){
    sum += nums[i];
  }
  console.log('합계', sum);
}

this

- 함수 내에서 this 키워드로 접근 가능
- 함수 컨텍스트 객체
- 함수를 호출한 객체에 대한 참조

순수 함수

- 동일한 입력값에 대해서 항상 동일한 출력을 하는 함수
- Side Effect가 없는 함수 -> 외부값에 영향을 주거나 받지 않는 함수

즉시 실행 함수 (IIFE 패턴)

- 함수 선언 후 곧바로 스스로를 호출하여 실행되는 함수
- 함수를 생성하고 호출하면 함수 내부에 선언된 변수는 사용하지 못하며 함수는 폐기된다.
- 외부에서 접근할 수 없는 독립적인 공간을 확보할 수 있음
- 코드를 함수로 감싸고 호출하면 해당 코드의 유표범위가 함수로 제한
- 함수 내에서 사용하는 변수는 외부에 노출되지 않으므로 외부 변수와 충돌이 발생하지 않는다.,

(() => {...})();

(() => {
  var alert = '즉시 실행 함수';
  console.log(alert);
})();

// 즉시 실행 함수로 alert를 선언했기 때문에 같은 이름의 변수를 사용해도 충돌이 발생하지 않는다
alert('작업 완료');

0개의 댓글