Programming/JavaScript

[JavaScript] 함수

앵도라지 2023. 2. 9. 22:07

 

자바스크립트는 다른 언어보다도 함수를 만드는 방법이 많다.

함수를 호출 할 때는 괄호 내부에 여러 가지 자료를 넣는데, 이런 자료를 매개변수라고 부른다. 그리고 함수를 호출해서 최종적으로 나오는 결과를 리턴값이라고 부른다.

 

 

1. 익명함수

  • 함수는 코드의 집합을 나타내는 자료형이고, 기본 형태는 function () {} 으로 표현한다.
  • 함수를 코드의 집합이라고 말하는 이유는 중괄호 {…} 내부에 코드를 넣기 때문이다.
  • 함수르라 실행하면 여러 코드를 한 번에 묶어서 실행할 수 있고, 필요할 때마다 호출해서 반복적으로 사용할수도 있다.
  • 자료형은 function이다.
  • 익명은 이름이 붙어있지 않은 함수를 표현한다.

 

2. 선언적 함수

  • 일반적으로 이름이 있는 함수를 가장 많이 사용한다. 이런 함수를 선언적 함수라고 한다.
  • 기본 형태는 let 함수 = function () {} ; 으로 표현한다.
  • 만드는 과정은 매우 간단하다.
  • 익명함수와의 차이점은 함수를 출력했을 때, 함수에 이름이 붙어있다는 것 뿐이다.

 

3. 매개변수와 리턴값

  • 함수를 호출할 때 괄호 안에 적는 것을 매개변수라고 한다.
    • prompt() 함수를 사용할 때 매개변수로 message를 넣어야 한다.
  • 함수의 최종 결과를 리턴값이라고 한다.
  • 모든 함수에 매개변수와 리턴값을 사용하는 것이 아니라 필요한 경우에만 매개변수와 리턴값을 사용한다.
function 함수 (매개변수, 매개변수, 매개변수) {
	문장
	문장
	return 리턴값
}
  • 함수에 넣는 input이 매개변수이고, 결과로 나오는 output이 리턴값이다.
    • 리턴값은 함수 내부에 return 키워드를 입력하고 뒤에 값을 넣어서 생성한다.

 

4. 나머지 매개변수

1) 나머지 매개변수란?

  • 어떨 때는 매개변수가 2개이고, 어떨 때는 20개인 함수를 구현하려면 어떻게 해야 할까?
  • 호출할 때 매개변수의 개수가 고정적이지 않은 함수를 가변 매개변수 함수라고 부른다.
  • 자바스크립트에서 이러한 함수를 구현할 때는 나머지 매개변수라는 특이한 형태의 문법을 사용한다.
  • function 함수 이름 (...나머지 매개변수) {} 형태로 구현한다.
  • 함수의 매개변수 앞에 마침표 3개(…)를 입력하면 매개변수들이 배열로 들어온다.
function sample(...items) {
	console.log(items)
}

sample(1, 3)
//[1, 3]
sample(1, 2, 3, 4, 5, 6)
//[1, 2, 3, 4, 5, 6]

 

2) 일반 매개변수와 나머지 매개변수의 조합

  • 나머지 매개변수는 일반적인 매개변수와 조합해서 사용할 수도 있다.
  • function 함수이름(매개변수, 매개변수, ...나머지 매개변수) {}
function sample(a, b, ...c) {
	console.log(a, b, c)
}

sample(1, 3)
//1 3 []
sample(1, 2, 3, 4, 5, 6)
//1 2 [3, 4, 5, 6]

 

3) 전개 연산자

  • 배열 요소에서 최솟값을 찾기 위해서는 min(array[0], array[1], array[2], array[3])와 같은 형태로 구할 것이다.
  • 이런 경우를 대비해 배열을 전개해서 매개변수로 전달하는 전개 연산자를 제공한다.
  • 함수이름(...배열) 과 같은 형태로 구현할 수 있다.
const array = [1, 2, 3, 4, 5]
console.log(array)
// [Array(5)]

console.log(...array)
// [1, 2, 3, 4, 5]

 

 

5. 기본 매개변수

  • 항상 같은 매개변수를 여러 번 반복해서 입력해야 할 때는 어떻게 구현할 수 있을까?
  • 매개변수에 기본값을 지정하는 기본 매개변수를 사용할 수 있다.
  • 함수 이름(매개변수, 매개변수=기본값, 매개변수=기본값) 형식으로 구현할 수 있다.
function earnings (name, wage=8590, hours=40) {
	console.log(`# ${name} 님의 급여정보`)
	console.log(`시급: ${wage}원`)
	console.log(`근무시간: ${hours}시간`)
	console.log(`급여: ${wage * hours}원`)
}
earnings('구름')
//# 구름 님의 급여 정보
//시급: 8590원
//근무시간: 40시간
//급여: 343600원

earnings('별', 10000, 52)
//# 별 님의 급여 정보
//시급: 10000원
//근무시간: 52시간
//급여: 520000원

 

 

6. 콜백함수

  • 자바스크립트는 함수도 하나의 자료형이므로 매개변수로 전달할 수 있다.
  • 이렇게 매개변수로 전달하는 함수를 콜백 함수라고 한다.
  • 다른 프로그래밍 언어에는 거의 찾아보기 힘든 개념이다.
function callThreeTimes(callback) {
	for (let i=0; i < 3; i++) {
		callback(i) //callback이라는 매개변수는 함수이므로 호출할 수 있다.
	}
}

function print (i) {
	console.log(`${i} 번째 함수 호출`)
}

callThreeTimes(print)

1) forEach() : 콜백함수를 활용하는 함수

  • 콜백함수를 활용하는 가장 기본적인 함수는 forEach()메소드다.
  • forEach() 메소드는 배열이 갖고 있는 함수(메소드)로서 단순하게 배열 내부의 요소를 사용해서 콜백함수를 호출해준다.
const numbers = [273, 52, 103, 32, 57]

numbers.forEach(function (value, index, array) {
	console.log(`${index}번째 요소 : ${value}`)
})

2) map() : 콜백 함수를 활용하는 함수

  • map() 메소드도 배열이 갖고 있는 함수다.
  • map() 메소드는 콜백 함수에서 리턴한 값들을 기반으로 새로운 배열을 만드는 함수다.
let numbers = [273, 52, 103, 32, 57]

numbers = numbers.map(function (value, index, array) {
	return value * value
})

numbers.forEach(console.log)

3) filter() : 콜백 함수를 활용하는 함수

  • filter() 메소드도 배열이 갖고 있는 함수다. filter() 메소드는 콜백 함수에서 리턴하는 값이 true인 것들만 모아서 새로운 배열을 만드는 함수다.
const numbers = [0, 1, 2, 3, 4, 5]
const evenNumbers = numbers.filter(function (value) {
	return value % 2 === 0
})

console.log(`원래 배열 : ${numbers}`)
//원래 배열 : 0, 1, 2, 3, 4, 5
console.log(`짝수만 추출 : ${evenNumbers}`)
//짝수만 추출 : 0, 2, 4

 

7. 화살표 함수

  • 단순한 형태의 콜백 함수를 쉽게 입력하고자 할 때 화살표 함수라는 함수 생성 방법을 사용한다.
  • function 키워드 대신 화살표 ( ⇒ )를 사용한다.
  • (매개변수) => 리턴값 형식으로 구현한다.
  • 내부에서 this 키워드가 지칭하는 대상이 다르다는 등의 미세한 차이가 있다.
let numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers
	.filter((value) => value % 2 === 0)
	.map((value) => value * value)
	.forEach((value) => {
		console.log(value)
	})
  • 위의 코드에서 filter() 메소드는 배열을 리턴하므로 map()메소드를 적용할 수 있고, map()메소드도 배열을 리턴하므로 forEach() 메소드를 적용할 수 있다.
    • 이렇게 어떤 메소드가 리턴하는 값을 기반으로 해서 함수를 줄줄이 사용하는 것을 메소드 체이닝이라고 부른다.

 

8. 타이머 함수

  • 특정 시간 마다, 특정 시간 이후에 콜백 함수를 호출할 수 있는 타이머 함수들이 자바스크립트에는 존재한다.
    • setTimeout(함수, 시간) : 특정 시간 후에 함수를 한 번 호출한다.
    • setInterval(함수, 시간) : 특정 시간마다 함수를 호출한다.
setTimeout(() => {
	console.log('1초 후에 실행된다')
}, 1*1000)

let count = 0

setInterval(() => {
	console.log(`1초마다 실행된다(${count}번째)`)
	count++
}, 1 * 1000)
  • 타이머를 종료하고 싶을 때는 clearTimeout() 함수와 clearInterval()함수를 사용한다.
    • clearTimeout(타이머_ID) : setTimeout()함수로 설정한 타이머를 제거한다.
    • clearInterval(타이머_ID) : setInterval()함수로 설정한 타이머를 제거한다.
let id
let count = 0
id = setInterval(() => {
	console.log(`1초마다 실행된다(${count}번째)`)
	count++
}, 1*1000)

setTimeout(() => {
	console.log('타이머를 종료한다.')
	clearInterval(id)
}, 5*1000)

추가내용

1) 즉시 함수 호출 - 블록, 함수블록

  • 코드가 여러 곳에서 사용되면 변수이름이 충돌할 가능성이 높다.
  • 다른 곳에서 가져온 코드와 내가 만든 코드에서 동일한 변수명이 존재한다면 어떻게 될까?
  • 변수가 존재하는 범위 스코프 는 같은 단계에 있을 경우 무조건 충돌이 일어난다.
  • 자바스크립트에서 스코프 단계를 변경하는 방법은 중괄호를 사용해서 블록을 만들거나, 함수를 생성해서 블록을 만드는 방법이다.
  • 충돌할 내용을 중괄호로 한 번 더 감싸주면 블록이 변경 되기 때문에 충돌이 일어나지 않는 것이다.
  • 내부 블록에서는 내부 블록에서 선언한 변수만 볼 수 있기 때문이다.
  • 이렇게 블록이 다른 경우 내부 변수가 외부변수를 가리는 현상을 섀도잉 이라고 한다.

2) 즉시 호출 함수 문제 해결하기

  • 구 버전의 자바스크립트에서 변수를 선언할 때 사용하던 var 키워드는 함수 블록을 사용하는 경우에만 변수 충돌을 막을 수 있다.
  • 함수 블록을 사용해 문제를 해결한다. 충돌 문제를 해결하기 위해 사용하는 것이다.

3) 엄격 모드

  • 블록의 가장 위쪽에 ‘use strict’라는 문자열이 등장하면, 엄격모드 기능이 실행되는 것이다.
  • 엄격 모드에서는 허용하던 오류를 모두 잡아낸다.

4) 익명 함수와 선언적 함수의 차이

  • while 반복문과 for 반복문은 2가지 모두 사용되지만, 사용하느 ㄴ상황이 다르다.
  • while 은 조건을 중심으로 반복할 때, for 은 횟수를 중심으로 또는 배열 등을 중심으로 반복할 때 사용한다.
  • 하지만 익명 함수와 선언적 함수는 사용하는 상황이 비슷하다.
  • 익명 함수는 일반적으로 코드를 읽을 때와 같은 순서로 함수가 선언된다. 하지만 선언적 함수는 우리가 코드를 읽는 순서와 다른 순서로 함수가 선언된다. 함수를 같은 이름으로 덮어쓰는 것은 굉장히 위험한 일이다. 따라서 안전하게 사용할 수 있는 익명 함수를 더 선호하는 것이다.