chasing_pavement

모던 자바스크립트 딥다이브 12장 본문

Javascript

모던 자바스크립트 딥다이브 12장

FE Developer, Jin 2024. 10. 25. 15:11

글을 보시는 분들이 계신다면 노션 내용을 이전 중이라서

줄바꿈이나 표식이 어색하게 되어 있는 곳이 아직 있다는 점 유의해주시면 감사하겠습니다ㅎㅎ

 

💡함수란?

일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것

 

 

함수 내부로 입력을 전달받는 변수: 매개 변수

입력: 인수

출력: 반환값

💡함수를 사용하는 이유?

중복을 제거하고 코드를 재사용하기 위해

→ 유지보수의 편의성 증가

→ 코드의 신뢰성 높아짐

💡함수 리터럴

function 키워드, 함수 이름, 매개변수 목록, 함수 몸체

함수 이름은 식별자라 네이밍 규칙을 준수해야 함.

함수 이름은 생략할 수 있음.

 

매개변수 목록은 소괄호로 감싸고 쉼표로 구분한다.

함수를 호출할 때 지정한 인수가 순서대로 할당되어 매개변수 목록은 순서에 의미가 있다.

💡함수 정의

 

1. 함수 선언문

함수 리터럴과 형태는 동일하지만 차이점이 있다.

함수 리터럴은 함수 이름을 생략할 수 있지만 함수 선언문은 이름을 생략할 수 없다.

 

함수 선언문은 표현식이 아닌 문이기 때문에 개발자 도구의 콘솔에서 선언물을 실행하면 undefined값이 출력된다.

만약 표현식이라면 undefined가 아니라 표현식이 평가되어 생성된 함수가 출력되어야 한다.

 

2. 함수 표현식

var add = function(x,y){
	return x+y;
};
console.log(add(2,5));

 

함수 리터럴의 함수 이름은 생략할 수 있는데 이런 함수를 익명 함수라고 한다.

 

 

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

console.dir(add); //add(x,y)
console.dir(sub); //undefined

console.log(add(2,5)); //7
console.log(sub(2,5)); //TypeError

//함수 선언문
function add(x,y){
	return x+y;
}

//함수 표현식
var sub = function(x,y){
	return x-y;
}

 

함수 선언문으로 정의한 함수는 선언문 이전에 호출할 수 있지만 함수 표현식으로 정의한 함수는 이전에 호출할 수 없다.

코드가 한 줄씩 순차적으로 실행되기 시작하는 런타임에는 이미 함수 객체가 생성되어 있고 함수 이름과 동일한 식별자에 할당까지 완료된 상태이다.

함수 선언문의 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅이라고 함.

 

3. Function 생성자 함수 : 일반적이지 않고 바람적이지 않기 때문에 사용을 추천하지 않음

var add = new Function('x','y','return x+y');
console.log(add(2,5));//7

 

4. 화살표 함수

const add = (x,y) => x+y;
console.log(add(2,5)); //7

 

항상 익명함수로 정의하고 생성자 함수로 사용할 수 없다.

표현도 간략하고 내부 동작 또한 간략화된 함수이다.

(26장에 구체적인 내용 언급 예정)

 

💡함수의 인수

function add(a,b,c){
	a = a || 0;
	b = b || 0;
	c = 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

위와 같이 인수가 전달되지 않은 경우 단축 평사를 사용하며 매개변수에 기본값을 할당할 수 있다.

이상적인 함수는 한 가지 일만 해야 하며 가급적 작게 만들어야 한다.

💡반환문

반환문을 사용해 실행 결과를 함수 외부로 반환(return) 할 수 있다.

function multiply(x,y){
	return x*y;
	//반환문 이후에 다른 문이 있으면 실행되지 않고 무시된다.
	console.log('실행X');
}
console.log(multiply(3,5)); //15

 

반환문의 역할

  1. 함수의 실행을 중단하고 함수 몸체를 빠져나간다.
  2. return 키워드 뒤에 오는 표현식을 평가에 반환한다.

*반환문을 생략하면 자동으로 undefined가 반환된다.

 

💡다양한 함수 형태

1. 즉시 실행 함수

함수 정의와 동시에 즉시 호출되는 함수

익명 함수를 사용하는 것이 일반적이지만 기명 즉시 실행 함수도 사용할 수 있다.

(function(){
	var a = 3;
	var b = 5;
	return a * b;

}());

 

2. 재귀 함수

자기 자신을 호출하여 반복되는 처리를 하는 함수

재귀 함수는 자신을 무한 호출하기 때문에 호출을 멈출 수 있는 탈출 조건을 반드시 만들어야 한다.

function factorial(n){
	if(n<=1) return 1;
	return n * factorial(n-1);
}

console.log(factorial(3)); //3!

 

3. 중첩 함수

함수 내부에 정의된 함수를 중첩(또는 내부)함수라고 한다. 중첩 함수를 포함하는 함수는 외부 함수라고 한다.

function outer() {
  var x = 1;

  // 중첩 함수
  function inner() {
    var y = 2;
    // 외부 함수의 변수를 참조할 수 있다.
    console.log(x + y); // 3
  }

  inner();
}

outer();

 

4. 콜백 함수

함수의 매개변수를 통해 다른 함수의 내부로 전달되는 함수

콜백 함수는 비동기 처리(이벤트 처리, Ajax 통신, 타이머 함수 …etc)에 활용되는 중요한 패턴

매개 변수를 통해 함수의 외부에서 콜백 함수를 전달받은 함수를 고차 함수라고 한다.

var logOdds = function(i){
	if(i%2) console.log(i);
};
//고차 함수에 함수 참조를 전달
repeat(5,logOdds); //1 3

 

5. 순수 함수와 비순수 함수

어떤 외부 상태에 의존하지도 않고 변경하지도 않는 함수 → 순수 함수

외부 상태에 의존하고 변경하는 함수 → 비순수 함수(=부수 효과가 있는 함수)

 

순수함수

var count = 0; // 현재 카운트를 나타내는 상태

//순수 함수
// 순수 함수 increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환한다.
function increase(n) {
  return ++n;
}

// 순수 함수가 반환한 결과값을 변수에 재할당해서 상태를 변경
count = increase(count);
console.log(count) // 1

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

console.log, alert 등으로 어떤 값을 출력하는 것은 부수 효과이다.

 

비순수함수

var count = 0; // 현재 카운트를 나타내는 상태: increase 함수에 의해 변화한다.

// 비순수 함수
function increase() {
  return ++count; // 외부 상태에 의존하며 외부 상태를 변경한다.
}

// 비순수 함수는 외부 상태(count)를 변경하므로 상태 변화를 추적하기 어려워진다.
increase();
console.log(count) // 1

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

하지만 이렇게 함수가 외부 상태를 변경하면 상태 변화를 추적하기 어려워진다.

그래서 비순수 함수를 사용하는 것은 지양하는 것을 추천한다.