본문 바로가기
JavaScript

자바스크립트#05 : 함수

by haheehee 2022. 12. 15.

자바스크립트에서 함수는 코드의 집합을 나타내는 자료형이다.


익명함수

function () { }

자바스크립트에서 이름을 부여 받지 못한 익명함수가 존재한다. 

(자바와는 다른점!)

<script>
	// 변수 생성
	const func = function() {
		console.log("함수 내부의 코드입니다 ...1")
		console.log("함수 내부의 코드입니다 ...2")
		console.log("함수 내부의 코드입니다 ...3")
		console.log("")
	}

	// 함수 호출
	func()
	func()

	// 출력
	console.log(typeof func)
	console.log(func)
</script>

func라는 변수에 익명함수를 선언하여 집어 넣었다. 

func는 참조 변수가 된 것이다.

위 코드에서 function () { }은 이름을 부여 받지 못한 익명함수이다.

익명함수 콘솔 출력창

이 경우, 참조변수를 기존의 alert(), prompt() 함수처럼 호출할 수 있다. 

typeof로 함수의 자료형을 확인하면, 익명함수의 자료형은 function으로 출력된다.

또한 함수 자체도 단순한 자료로 다루어지기 때문에 출력이 가능하다.

 


선언적 함수 (명명함수)

선언적 함수는 이름을 붙인 함수이다.

function name() { }

명명함수는 함수명을 넣어야 한다.

 

이것은

let name = function () { };

이러한 기능을 수행한다.

 

<script>
	function func() {
		console.log("함수 내부의 코드입니다 ...1")
		console.log("함수 내부의 코드입니다 ...2")
		console.log("함수 내부의 코드입니다 ...3")
		console.log("")
	}

	func()
	func()

	console.log(typeof func)
	console.log(func)
</script>

익명함수에서와 다르게 func라는 이름을 함수에 명명해주었다. 

선언적 함수 콘솔 출력창

선언적 함수 func를 콘솔창에 출력하면, 

위의 익명함수와 다르게 명명된 이름까지 콘솔창에 출력된다.


함수의 매개변수와 리턴값

function prompt(message?:string, _default?:string):string

prompt() 함수 선언부의 기본형을 나타낸 것이다. 

 

여기서 제일 첫번째 단어인 function은 예약어이다.

 

매개변수는 1. message와 2. _default로 두가지이다.

매개변수는 두가지 모두 string형이며,

매개변수에서 ?의 의미는 null을 허용한다는 것이다.(이것은 공간의 특성을 살려준다.)

매개변수 두 가지 모두 ?을 포함하므로, 위 함수는 매개변수 없이 호출이 가능하다.

매개변수에 ?이 포함되지 않았다면, 함수 호출시에 일대일대응으로 모든 매개변수가 명시되어야 한다.

 

리턴은 제일 마지막 단어 :string이 리턴값을 나타내는데, 문자열을 리턴값으로 갖는다는 의미이다. 

 


function 함수이름 (매개변수1, 매개변수2, 매개변수3) {
	실행문
    
	return 리턴값
}

여기서 매개변수 1, 2, 3이 모두 number형이라면, 

리턴값을 따로 선언부에 명시하지 않아도 number형이 도출되므로, 

return값을 선언부에서 생략해도 된다.

 

같은 흐름으로

실행문 부분에 산술연산이 들어있는 함수라면, 

매개변수와 리턴값 모두 number형이라 유추하여 선언할 수 있겠다.


지금까지의 내용으로 

윤년을 확인하는 함수를 만들어보겠다.


윤년의 조건은 다음의 세가지를 충족시켜야 한다.

1. 4로 나누어 떨어지는 해

2. 100으로 나누어 떨어지는 해는 제외

3. 400으로 나누어 떨어지는 해는 포함

<script>
	function leapYear(year) {
		return (year%4 === 0) && (year%100 !== 0) || (year%400 === 0)
	}
	
	console.log(`2020년은 윤년일까? => ${leapYear(2020)}`)
	console.log(`2022년은 윤년일까? => ${leapYear(2022)}`)
	console.log(`2000년은 윤년일까? => ${leapYear(2000)}`)
	console.log(`1900년은 윤년일까? => ${leapYear(1900)}`)
</script>

윤년 출력 콘솔창

이렇게 매개변수와 리턴값의 자료형을 선언부에서 생략해도 문제없이 작동되는 것을 확인할 수 있다.


가변 매개변수

나머지 매개변수라고도 불리운다. (rest parameter)

function 함수_이름(...가변_매개변수_이름) { }

매개변수의 개수가 고정적이지 않고 가변적인 형태를 말한다. 

null값이 들어갈 수도 있음!(값이 들어가지 않을 수 도 있다)

함수에 나머지 매개변수를 파라미터로 넣어서 실행시키면, 연속된 공간을 만들어 저장한다.

<script>
	function min(...items) {
		let output = items[0]
		for(const item of items) {
			if(output > item) {
				output = item
			}
		}
		return output
	}
	
	console.log("min(52, 35, 155, 32, 266, 275, 31, 60)")
	console.log(` = ${min(52, 35, 155, 32, 266, 275, 31, 60)}`)
</script>

위 코드에서 매개변수 items는 배열처럼 사용한다. 

나머지 파라미터 콘솔 출력창

 


function 함수_이름(매개변수1, 매개변수2, ...가변매개변수) { }

가변 매개변수를 일반 매개변수와 조합할 수 있다. 

하지만 가변매개변수가 앞으로 들어간다면, 함수 호출시 넣은 매개변수가 다 가변매개변수로 들어가기 때문에, 순서에 유의하여야 한다.


Array.isArray() 함수

매개변수로 들어온 자료형이 배열인지 숫자인지 확인하는 함수

일반적인 typeof 연산자로는 배열임을 확인할 수 없다. (자바에서의 instanceof가 자바스크립트에서는 typeof)

function min(first, ...rests) {
	let output
	let items
	
	if(Array.isArray(first)) {
		output = first[0]
		items = first
	} else if (typeof(first) === "number") {
		output = first
		items = rests
	}
    	for(const item of items) {
		if(output > item) {
			output = item
		}
	}
	return output
}

가변 매개변수 -> 전개 연산자

전개 연산자는 배열을 전개하여 함수의 매개변수로 전달하는 연산자

<script>
	function sample(...items) {
		console.log(items)
	}
	
	const array = [1, 2, 3, 4]
	
	console.log("# 전개 연산자를 사용하지 않은 경우")
	sample(array)
	console.log("# 전개 연산자를 사용한 경우")
	sample(...array)	
</script>

전개연산자에 따른 결과


매개변수의 기본값 지정

자바스크립트에서는 매개변수에 기본값을 지정할 수 있다. 

<script>
	function earnings(name, wage=9160, hours=48) {
		console.log(`# ${name}님의 급여 정보`)
		console.log(`- 시급 : ${wage}원`)
		console.log(`- 근무 시간 : ${hours}시간`)
		console.log(`- 급여 : ${wage * hours}원`)
		console.log("")
	}
	
	earnings("최정임")
	earnings("김만원", 10000)
	earnings("오십이", 10000, 52)
</script>

매개변수의 기본값 지정


매개변수에는 기본값을 

매개변수=new Date().getFullYear()

이런식으로 넣을 수도 있다.

 


콜백 함수

자바스크립트는 함수도 하나의 자료형으로 간주한다. 

따라서 함수도 매개변수에 넣어 전달할 수 있다.

이렇게 매개변수로 전달하는 함수 = 콜백함수

콜백함수로 선언적 함수 사용
콜백함수로 익명 함수 사용

 

콜백함수 - forEach()

콜백함수에서 지원되는 메소드인 forEach()

forEach() 메소드는 배열이 가지고 있는 함수로, 단순히 배열 내부의 요소를 사용하여 콜백 함수를 호출한다.

function(value, index, array) { }

<script>
	const numbers = [309, 13, 253, 33, 55]
	
	numbers.forEach(function (value, index, array) {
		console.log(`${index}번째 요소 : ${value}`)
	})
</script>

익명함수가 forEach()의 매개변수로 들어갔다. 

forEach()

 

콜백함수 - map()

map() 메소드는 콜백함수에서 리턴한 값들을 기반으로 새로운 배열을 만드는 함수이다.

<script>
	let numbers = [398, 18, 30, 355, 14]
	
	numbers = numbers.map(function(value) {
		return value * value
	})
	
	numbers.forEach(console.log)
</script>

매개변수로 value, index, array를 가질 수 있다. 

위 코드에서는 value 값을 매개변수로 가짐.(함수 내부에서 value만 사용하므로)

매개변수로 console.log 메소드 자체를 넣었다.

map()

 

콜백함수 - filter()

forEach()는 모든 요소를 사용하여 콜백을 호출했다면, 

filter() 함수는 내가 원하는 요소만!

콜백 함수에서 리턴하는 값이 true인 요소들만 모아서 새로운 배열을 만드는 함수이다. 

<script>
	const numbers = [1, 2, 3, 4, 5, 6, 7]
	const evenNumbers = numbers.filter(function (value, index, array) {
		return value%2 === 0
	})
	
	console.log(`원래 배열: ${numbers}`)
	console.log(`짝수만 추출: ${evenNumbers}`)
</script>

filter()


람다식

화살표함수

function 키워드 대신 화살표 (=>)를 사용

 

(매개변수) => 리턴값
(매개변수) => {
} 불표현식||불표현식이거짓일때실행할_실행문

위 형식으로 사용한다.

 

<script>
	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))
</script>

하단과 같이 메소드를 연속적으로 사용하는것을 메소드 체이닝이라고 한다.

람다식

 

 

람다식 - 타이머 함수

콜백함수를 호출할 수 있는 timer 함수

 

- setTimeout(함수, 시간) : 특정 시간 에 함수를 한 번 호출

- setInterval(함수, 시간) : 특정 시간마다 함수를 호출 (간격)

타이머를 종료하지 않으면 무한 실행되므로 종료를 해주어야 한다. 

- clearTimeout(타이머_ID) : setTimeout()로 설정한 타이머 제거

- clearInterval(타이머_ID) : setInterval()로 설정한 타이머 제거

<script>
	let id
	let count = 0
	id = setInterval(() => {
		console.log(`1초마다 실행됩니다. (${count}번째)`)
		count++
	}, 1 * 1000)
	
	setTimeout(() => {
		console.log(`타이머를 종료합니다.`)
		clearInterval(id)
	}, 5 * 1000)
</script>

람다식 - 타이머


즉시호출함수 #1

<script>
	let pi = 3.14
	console.log(`파이 값은 ${pi}입니다.`)
	
	{
		let pi = 3.141592
		console.log(`파이 값은 ${pi}입니다.`)
	}
	console.log(`파이 값은 ${pi}입니다.`)
	
	function sample() {
		let pi = 3.141592
		console.log(`파이 값은 ${pi}입니다.`)
	}
	sample()
	console.log(`파이 값은 ${pi}입니다.`)
</script>

다른 블록에 속하면 변수 이름이 같아도 오류가 발생하지 않는다. 

즉시호출함수 #1

기묘하다..


let 키워드 대신 var 키워드를 사용하면 변수 충돌을 막을 수 있다. (같은 블록내에서도)

var 키워드는 덮어 쓰기 때문!


엄격모드

'use strict'라는 문자열을 블록의 가장 위쪽에 삽입하면, 

코드를 엄격하게 검사한다. 

가령, 'use strict'없이 "키워드 없이 선언하여 출력한 코드"를 실행시켜도 잘 실행되었던 것이 오류가 나는것처럼,,


함수의 생명주기

-익명함수 : 미리 생성되지 않고, 코드를 실행할 때 해당 줄에 도달하면 익명함수가 생성됨. 

- 명명함수 : 순차적인 코드 실행이 일어나기 이전에 생성됨. (컴파일할 때 만들어진다.)

 

 

 

 

 

 

 

 

 

 

 

출처 : 혼자 공부하는 자바스크립트 (윤인성)

 

댓글