본문 바로가기

웹 프로그래밍/JavaScript

[JS] 함수 생성 및 활용 (함수 호이스팅, arguments, callback 함수)

자바스크립트에서는 메소드라고 하지 않고, 함수라고 부른다.

자바와 다른 점은, 반환 타입과 매개변수 타입을 지정하지 않는 것이다. 왜? 다 var 형이기 때문이다.

그리고, 객체를 생성해서 활용하지 않고 함수 단독으로 사용할 수 있다.

 

 

prompt에서는 숫자를 써도 스트링으로 날라간다. 그래서 Number 변환 필요하다.

그런데, 함수에서는 숫자 그대로 날라간다. 즉, Number 변환이 필요 없다. 아래의 sum 함수 예제를 보자.

	let cnt = 0;
	do{
		
		let name = prompt('이름을 입력하세요');
		let age = prompt('나이를 입력하세요');
		age = Number(age);
		alert(name + '의 10년 후의 나이는 ' + (age + 10) + '입니다.'); // number형으로 바꾸지 않으면, concat 된다.
		alert(++cnt + '번째 입력되었습니다.')
	
	} while(confirm('계속하시겠습니까?'));
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	function testFunction(){
		alert('call...');
	}
	
	function testFunction2(data){
		alert('data: ' + data);
	}
	
	function testFunction3(data1, data2){
		alert(`data1 : ${data1}, data2 : ${data2}`);
	}
	
	function sum(data1, data2){

		return data1 + data2
	}

	var total = sum(10,50);
	alert(total);
	
	testFunction2(200);
	testFunction2("hello"); // 자바스크립트는 아주 유연하다. 데이터 유형이 바뀌어도 된다.
	testFunction3('A', 12.34);
	
	
</script>
</head>
<body>

</body>
</html>

 

 

자바스크립트에서 함수는 오버로딩 지원이 안된다. 마지막에 선언된 함수가 적용된다.

 

 

함수 호이스팅

그런데, 함수 선언보다 함수 호출이 먼저 나온다면 실행이 될까?

>>> 선언적 함수에서는 호이스팅이 발생하기 때문에 가능하다. 

>>> 그러나, 익명적 함수에서는 호이스팅이 발생하지 않기 때문에 불가능하다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	//선언적 함수
	function testFunction() {
		alert('call...');
	}

	function testFunction2(data) {
		alert('data : ' + data);
	}

	function testFunction3(data1, data2) {
		alert(`data1 : ${ data1 }, data2 : ${ data2 }`);
	}

	function sum(a, b) {
		return a + b;
	}

	aaa(1, 2, 3, 4, 5);

	function aaa(data) {
		alert('call aaa(data)');
	}

	function aaa(a, b) {
		alert('call aaa(a, b)');
	}

	function aaa() {
		alert('call aaa()');
	}

	var total = sum(12, 45);
	alert('총합 : ' + total);

	testFunction();
	testFunction2(100);
	testFunction2("hello");
	testFunction3('A', 12.34);
</script>
</head>
<body>

</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	var temp = function func(){
		alert('call func()');
	}
	
	temp();
	func(); // 호출이 안 된다.
	
	
	func01(); // 실행 안 된다. 익명함수는 함수 호이스팅이 안 된다.
	
	// 익명함수 선언
	var func01 = function(){
		alert('익명함수 call func01()...');		
	}
	
	func01(); // 실행 된다.
	
	
</script>
</head>
<body>

</body>
</html>

 

주의 사항

- 선언적 함수는 호이스팅이 발생하기 때문에, aaa() 함수는 익명함수를 호출한다.

- 같은 함수명이 있다면, 무조건 익명함수가 실행된다고 생각하면 된다. 

<script>

	var aaa = function(){
		alert('익명함수 aaa() 호출...');
	}
	
	function aaa(){
		alert('선언함수 aaa() 호출...');
	}
	
	aaa(); // 뭐가 호출될까?
	
	
</script>

 

 

함수의 내부에서만 사용하는 함수를 선언할 수도 있다.

	function printSum(a, b) {
		//alert('1 ~ 10사이의 총합 : ' + getSum(a, b));
		
		function sum(a, b) {
			let s = 0;
			while(a <= b) {
				s += a++;
			}
			return s;
		}
		alert('1 ~ 10사이의 총합 : ' + sum(a, b));
	}
	

	function sum(a, b) {
		return a + b;
	}
    
    // sum(1, 10) 하면 11이 나오겠지요.

 

주의 : 매개변수가 일치하지 않아도 함수가 호출된다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	function aaa(){
		
	}
	
	function aaa(a, b){
		
	}
	
	aaa(1,2,3,4,5); // 이래도 aaa(a,b) 함수가 호출된다.

</script>
</head>
<body>

</body>
</html>

 

Arguments

: arguments 정보를 가지고 있다. 이를 활용해 매개변수의 개수에 따라 다른 로직을 타야한다. 왜? 매개변수의 개수가 적절하지 않아도 실행이 되기 때문에 로직 상에 문제가 생길 수 있다.

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script>
	
	function aaa(a, b){
		switch(arguments.length){
		case 0:
			alert('call aaa()...');
			break;
		case 1:
			alert('data : ' + arguments[0]);
			break;
		case 2:
			alert('a : ' + arguments[0] + " b : " + arguments[1]);
			break;
		
		}
		
	}
	
	aaa("hello", 20);
	
	 
	
</script>
</head>
<body>

</body>
</html>

 

 

콜백함수

매개변수로 익명함수를 받는다.

callbackFunc 함수 내에서 익명함수를 재정의해서 사용한다. 굉장히 많이 쓰이는 개념이다.

 

-

 

누군가가 함수를 호출하는데, 매개변수로 함수명을 쓴다.

호출을 당한 함수입장에서는 매개변수가 변수가 아니라, 다른 함수가 나온다. 그게 바로 콜백이다.

그때그때 함수가 달라지니까 좀 더 유연하게 만들 수 있다.

 

@@@@콜백함수 정리 필요@@@@

 

매개변수로 함수를 받는 함수를 콜백함수라고 한다.

 

[예제]

setTimeout(함수, ms)  : setTimeout 함수는 콜백함수 형태로 쓰인다. 왜? 사용자마다 활용하고자 하는 함수(매개변수로 오는)함수가 다르기 때문

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script>
/*
 	자바스크립트 내장함수
 	1. 타이머
 		setTimeout(함수, ms) 	: setTimeout 함수는 콜백함수 형태로 쓰인다. 왜? 사용자마다 활용하고자 하는 함수(매개변수로 오는)함수가 다르기 때문
 		setInterval(함수, ms)	: 주기적으로 활용하는 타이머인듯?
 		clearInterval(id)
 		clearTimeout(id)
 */
 	var func = function() {
 			alert('3초가 지났습니다.');
 		}
 		 		
 	setTimeout(func, 3000);
 	// 위와 같이, 함수를 먼저 정의하고 그것을 매개변수로 쓰는 형태로 잘 쓰지 않는다.
 	
 	// 매개변수의 위치에 바로 함수를 정의해서 쓰는 형태를 더 많이 쓴다.
 	setTimeout(function(){
 		alert('3초가 지났습니다.');
 	}, 3000);
 	
 	
 	var id = setInterval(function(){
 		document.write('현재 시간 : ' + new Date() + '<br>');
 	}, 1000); // 1초마다 주기적으로 함수를 호출하지요.
 	
 	

 	setTimeout(function(){
 		alert('날짜 쓰기 종료...');
 		clearInterval(id);
 	}, 10000); // 10초 후에 id라는 타이머 함수를 멈춘다.
 
 		
 
</script>
</head>
<body>

</body>
</html>