Study Web Development

12월 20일

이전으로

JavaScript

6. 함수

함수의 역할

6-1 함수의 정의와 호출

  1. 새 폴더 ch05-function 생성하고 새 HTML 파일 s01_function.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>함수</title>
<script type="text/javascript">
	// 선언적 함수
	function check() {
		document.write('호출하면 동작함<br>');
	}
	// 함수 호출
	check();
	
	// 인자가 있는 함수
	function check2(msg) { // 인자 앞에 var를 명시하면 에러
		document.write(msg + '을 좋아합니다.<br>');
	}
	// 함수 호출
	check2('가을');
	
	// 반환값이 있는 함수
	function check3(num) {
		return num*num;
	}
	// 함수 호출
	var number = check3(10);
	document.write('number = ' + number + '<br>');
	
	document.write('--------<br>');
	
	// 익명 함수
	var play = function() { // 변수명이 익명 함수의 이름을 대신함
		document.write('게임을 좋아해요!<br>');
	}; // 변수를 선언하는 것으로 간주하므로 세미콜론 필요
	// 함수 호출
	play();
	
	// 인자가 있는 익명 함수
	var play2 = function(item) {
		document.write(item + '를 좋아합니다!<br>');
	};
	// 함수 호출
	play2('초코');
	
	// 반환값이 있는 익명 함수
	var play3 = function(x, y) {
		return x + y;	
	};
	// 함수 호출
	var result = play3(5, 8);
	document.write('result = ' + result + '<br>');
	
	document.write('--------<br>');
	
	function checkIt() {
		alert('오늘은 월요일입니다.');	
	}
</script>
</head>
<body>
	<input type="button" value="확인" onclick="checkIt();"> <!-- 인라인 방식으로 HTML 태그와 자바스크립트 함수를 연결 -->
</body>
</html>
  1. 새 HTML 파일 s02_function.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>함수</title>
<script type="text/javascript">
	// 함수의 이름이 같으면 마지막에 정의한 함수가 동작
	function 함수() {
		document.write('함수 A<br>');
	}
	function 함수() {
		document.write('함수 B<br>');
	}
	// 함수 호출
	함수();
	
	document.write('--------<br>');
	
	// 함수 호이스팅
	함수2();
	// 함수 선언
	function 함수2() {
		document.write('함수2<br>');
	}
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s03_function.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>익명 함수</title>
<script type="text/javascript">
	// 익명 함수를 동일한 이름의 변수에 대입하고 호출하면 마지막에 대입한 함수가 호출됨
	var 함수1 = function() {
		document.write('함수 A<br>');
	};
	var 함수1 = function() {
		document.write('함수 B<br>');
	};
	// 함수 호출
	함수1();
	
	document.write('--------<br>')
	
	// 익명 함수로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생함; 즉, 익명 함수를 정의하기 전에 함수를 호출하면 undefined를 호출하는 것과 마찬가지이므로 타입 에러가 발생
	// 함수2();
	// 함수 선언
	var 함수2 = function() {
		document.write('함수2<br>');
	};
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s04_scope.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>전역 변수와 지역 변수</title>
<script type="text/javascript">
/* 
1. 지역 변수(함수 레벨 스코프)
함수 안에서 var를 사용해서 선언한 변수
함수가 끝나면 소멸

2. 전역 변수
함수 밖에서 만들어진 모든 변수
함수 안에서 var 없이 만들어진 변수
함수가 끝나도 메모리에 남아 있음
*/
	function test1() {
		var i = 10; // 지역 변수
		document.write(i + '<br>');
	}
	// 함수 호출
	test1();
	// 지역 변수는 함수가 종료되면 소멸되기 때문에 함수 밖에서 호출 불가
	// document.write(i + '<br>');
	
	var j; // 전역 변수
	function test2() {
		j = 200;
		document.write(j + '<br>');
	}
	// 함수 호출
	test2();
	
	// 전역 변수는 함수가 끝나도 재사용 가능; 메모리에 부담을 줄 수 있으므로 전역 변수의 사용은 최소화해야 함
	function test3() {
		document.write(j + '<br>');
	}
	// 함수 호출
	test3();
	
	// var를 명시하지 않고 전역 변수를 만드는 경우에는 선언과 함께 초기화해야 함; 다만 이런 식의 전역 변수 선언은 혼동을 줄 수 있으므로 권장되지 않음
	a = 10; // 전역 변수; 초기화하지 않고 선언만 하면 not defined로 간주됨
	function test4() {
		a = 100;
		document.write(a + '<br>');
	}
	// 함수 호출
	test4();
	
	function test5() {
		m = 300; // 전역 변수; 단, 이런 식의 전역 변수 선언은 혼동을 줄 수 있으므로 권장되지 않음
		document.write(m + '<br>');
	}
	// 함수 호출
	test5();
	
	// 전역 변수는 함수가 끝나도 재사용 가능
	function test6() {
		document.write(m + '<br>');
	}
	// 함수 호출
	test6();	
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s05_scope.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>let</title>
<script type="text/javascript">
/* 
블럭 레벨의 스코프 : let(변수), const(상수)
ES6에서 변수를 정의하는 데 let을 사용할 수 있고, 상수를 정의하는 데는 const를 사용할 수 있으며, 이들은 블럭 레벨의 스코프를 가짐

*/
	for(let i=1;i<=3;i++) {
		document.write(i + '<br>');
	}
	// document.write(i + '<br>'); // let으로 선언한 변수는 블럭 밖에서 호출 불가; var로 선언시에는 블럭 밖에서도 호출 가능
	
	document.write('--------<br>');
	
	function test1() {
		let i = 20; // 지역 변수
		document.write(i + '<br>');
	}
	// 함수 호출
	test1();
	// document.write(i + '<br>'); // let으로 선언한 변수는 함수 블럭 밖에서 호출 불가

	document.write('--------<br>');
	
	function test2() {
		let a = 30; // 지역 변수
		document.write(a + '<br>');
		
		// let a = 40; // let으로 선언한 변수는 중복 선언시 에러 발생 
		// document.write(a + '<br>');
	}
	// 함수 호출
	test2();

	document.write('--------<br>');
	
	let n = 50; // 전역 변수
	function test3() {
		document.write(n + '<br>');
	}
	// 함수 호출
	test3();
	// 전역 변수는 함수가 끝나도 재사용 가능
	document.write(n + '<br>');
	
	// let로 선언한 변수는 변수 호이스팅이 적용되지 않음
	// document.write(score);
	// 변수 선언
	// let score;
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s06_scope.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>const</title>
<script type="text/javascript">
	function test() {
		const b = 20; // 상수
		document.write(b + '<br>');
		
		// b = 30; // const로 선언한 상수는 값 변경 불가
		// document.write(b + '<br>');
	}
	// 함수 호출
	test();
	// document.write(b + '<br>'); // const로 선언한 상수는 블럭 밖에서 호출 불가
</script>
</head>
<body>

</body>
</html>

6-2 매개 변수

  1. 새 HTML 파일 s07_parameter.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>함수의 인자</title>
<script type="text/javascript">
	// 자바스크립트는 함수를 생성할 때 지정했던 매개 변수보다 많거나 적은 매개 변수를 사용하는 것을 허용함; 원래 함수에서 선언했던 매개 변수보다 적게 사용하는 경우, 미지정 매개 변수는 undefined로 처리됨
	function test(a, b) {
		document.write('a = ' + a + '<br>');
		document.write('b = ' + b + '<br>');
	}
	// 함수 호출
	test(10);
	document.write('--------<br>');
	test(10, 20);
	document.write('--------<br>');
	test(10, 20, 30);
</script>
</head>
<body>

</body>
</html>

6-3 가변 인자 함수

  1. 새 HTML 파일 s08_parameter.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>가변 인자 함수</title>
<script type="text/javascript">
	function test() {
		for(var i=0;i<arguments.length;i++) {
			document.write('arguments[' + i + ']: ' + arguments[i] + '<br>');
		}
	}
	// 함수 호출
	test(10);
	document.write('--------<br>');
	test(10, 20);
	document.write('--------<br>');
	test(10, 20, 30);
</script>
</head>
<body>

</body>
</html>

6-5 return값의 활용

  1. 새 HTML 파일 s09_return.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>return</title>
<script type="text/javascript">
	function returnTest1(x, y) {
		return x + y; // 값을 반환
	}
	// 함수 호출
	var result = returnTest1(3, 5);
	document.write(result + '<br>');
	
	document.write('--------<br>');
	
	function returnTest2() {
		document.write('문장 A<br>');
		
		for(var i=1;i<=10;i++) {
			if(i == 5) {
				// break; // 조건 만족시 현재 반복을 중지하고 for문을 빠져나감
				return; // 조건 만족시 함수를 빠져나가 함수가 종료됨
			}
			document.write(i + '<br>');
		}
		
		document.write('문장 B<br>'); // break일 때는 실행되고, return일 때는 실행되지 않음
	}
	// 함수 호출
	returnTest2();
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s10_practice.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>실습</title>
<script type="text/javascript">
/* 
[실습 문제]
키와 몸무게를 입력해서 적정 몸무게를 구하는 함수 avgWeight를 만들어 보자.
함수에 키와 몸무게를 전달하면 다음 예와 같이 출력되게 작성해 보자.
적정 몸무게를 구하는 공식 : (height - 100) * 0.9

[출력 예시]
당신의 키는 00cm이고 현재 몸무게는 00kg이며 적정 몸무게는 00kg입니다.
적정 몸무게(적정 몸무게 초과, 적정 몸무게 미만)
*/
	function avgWeight(height, weight) {
		// 적정 몸무게 구하기
		var balance = (height - 100) * 0.9;
		
		document.write('당신의 키는 ' + height + 'cm이고 현재 몸무게는 ' + weight + 'kg이며 적정 몸무게는 ' + balance + 'kg입니다.<br>');
		
		document.write('적정 몸무게');
		if(weight>balance) {
			document.write(' 초과');
		}
		else if(weight<balance) {
			document.write(' 미만');
		}
	}
	
	// prompt를 이용해서 값을 입력받음
	var height = Number(prompt('키를 입력하세요.', ''));
	var weight = Number(prompt('몸무게를 입력하세요.', ''));
	
	// 함수 호출
	avgWeight(height, weight);
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s11_practice.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>실습</title>
<script type="text/javascript">
/*
[실습 문제]
국어(korean), 영어(english), 수학(math) 성적을 prompt로 입력 받아서 총점(getSum), 평균(getAvg), 등급(getGrade)을 구하는 함수를 정의하고 출력하시오.
*/
	// 총점 구하기
	function getSum(korean, english, math) {
		return korean + english + math;
	}
	
	// 평균 구하기
	function getAvg(sum) {
		return sum/3;
	}
	
	// 등급 구하기
	function getGrade(avg) {
		var grade;
		if(avg>=90 && avg<=100) grade = 'A';
		else if(avg>=80) grade = 'B';
		else if(avg>=70) grade = 'C';
		else if(avg>=60) grade = 'D';
		else grade = 'F';
		return grade;
	}
	
	// 입력받는 값 검사
	function checkScore(guide) {
		while(true) {
			var score = Number(prompt(guide, ''));
			if(score>=0 && score<=100) break;
			alert('성적은 0부터 100 사이의 값만 입력 가능합니다!');
		}
		return score;
	}
	
	// 성적 입력	
	var korean = checkScore('국어 점수를 입력하세요');
	var english = checkScore('영어 점수를 입력하세요', '');
	var math = checkScore('수학 점수를 입력하세요', '');

	// 계산
	var sum = getSum(korean, english, math);
	var avg = getAvg(sum);
	var grade = getGrade(avg);
	
	// 출력
	document.write('총점 : ' + sum +'<br>');
	document.write('평균 : ' + avg +'<br>');
	document.write('등급 : ' + grade +'<br>');
</script>
</head>
<body>

</body>
</html>

6-6 내부 함수

  1. 새 HTML 파일 s12_inner.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>내부 함수</title>
<script type="text/javascript">
	function f() {
		// 내부 함수 정의
		function g() {
			document.write('g is called');
		}
		// 내부 함수 호출; f()를 정의할 때 f() 내부에서 g()를 호출하더라도, 외부에서 f()를 호출해야 g()가 실행됨
		g();
	}
	// 함수 호출
	f();
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s13_inner.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>내부 함수</title>
<script type="text/javascript">
	function f() {
		// 지역 변수 선언 및 초기화
		var n = 123;
		// 내부 함수 정의
		function g() {
			document.write('n is ' + n + '<br>');
			document.write('g is called');
		}
		// 내부 함수 호출
		g();
	}
	// 함수 호출
	f();
</script>
</head>
<body>

</body>
</html>

6-7 함수를 반환하는 함수와 클로저

  1. 새 HTML 파일 s14_inner.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>내부 함수</title>
<script type="text/javascript">
	function f() {
		// 지역 변수 선언 및 초기화
		var n = 123;
		// 내부 함수
		function g() {
			document.write('n is ' + n + '<br>');
			document.write('g is called<br>');
		}
		return g; // 함수 정보 반환
	}
	// 함수 호출
	var m = f(); // f()는 내부 함수 g를 반환하여 m에 대입
	document.write(m + '<br>'); // g 선언 코드 출력
	
	document.write('--------<br>');
	
	// 변수 m에 대입된 함수 g를 호출; 함수 f가 종료되었음에도 f의 지역 변수인 n이 계속 사용되고 있음
	m();
	
	document.write('--------<br>');
	
	// f()가 함수 g를 의미하므로, f()에 ()를 붙이면 g()가 되어 함수 g 호출 가능
	f()();
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s15_inner.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>클로저</title>
<script type="text/javascript">
/* 
지역 변수는 함수가 실행될 때 생성되고 함수가 종료될 때 사라짐
하지만 클로저를 사용하면 이 규칙을 위반할 수 있음
지역 변수를 남겨두는 현상을 클로저라고 함
내부 함수를 이용해서 지역 변수를 호출할 때 지역 변수가 선언된 함수가 종료되어도 클로저를 이용해서 내부 함수 내에서 지역 변수를 호출 가능함
*/
	function outerFunction(name) {
		// 지역 변수
		var output = 'Hello ' + name + '!!!';
		
		// 선언적 함수
		/*
		function g() {
			alert(output);
		}
		return g;
		*/
		
		// 익명 함수
		return function() {
			alert(output); // outerFunction의 지역 변수 호출
		};
	}
	
	// 변수를 만들어 outerFunction의 내부 함수 호출하기
	// var result = outerFunction('너굴');
	// result();
	
	// 변수를 만들지 않고 outerFunction의 내부 함수 호출하기
	outerFunction('콩돌')();
</script>
</head>
<body>

</body>
</html>

6-8 내장 함수

  1. 새 폴더 ch06-nestedFunction 생성하고 새 HTML 파일 s01_isFinite.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>isFinite 함수</title>
<script type="text/javascript">
	var number1 = -10 / 0; // 양수를 0으로 나누면 Infinity, 음수를 0으로 나누면 -Infinity 반환
	document.write('number1 = ' + number1 + '<br>');
	
	// Infinity에 부호가 있기 때문에 조건문 작성이 번거로움
	if(number1 == Infinity) { // 0으로 나누는 경우
		document.write('무한<br>');
	}
	else { // 0이 아닌 수로 나누는 경우
		document.write('유한<br>');
	}
	
	// 주어진 값이 유한한지 판별하는 isFinite 함수를 사용하면 Infinity의 부호를 고려할 필요 없음
	if(isFinite(number1)) { // 0이 아닌 수로 나누는 경우
		document.write('유한');
	}
	else { // 0으로 나누는 경우
		document.write('무한');
	}
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s02_isNaN.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>isNaN 함수</title>
<script type="text/javascript">
	var number1 = 10 / 'A';
	document.write('number1 = ' + number1 + '<br>'); // NaN(Not a Number) 출력
	
	// NaN은 ==나 ===로 판별할 수 없음; NaN==NaN, NaN===NaN 모두 false를 반환하기 때문
	if(number1 == NaN) {
		document.write('숫자가 아닙니다!<br>');
	}
	else {
		document.write('숫자입니다.<br>');
	}
	
	// 주어진 값이 숫자인지 판별하는 isNaN 함수를 사용해야 함
	if(isNaN(number1)) {
		document.write('숫자가 아닙니다!');
	}
	else {
		document.write('숫자입니다.');
	}
</script>
</head>
<body>

</body>
</html>
  1. 새 HTML 파일 s03_parseInt.html 생성
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>parseInt, parseFloat</title>
<script type="text/javascript">
	var num = '1234';
	var won = '1000원';
	var won2 = '원1000';
	var won3 = '10원00'
	
	var num2 = '24.56';
	var dollar = '1.5$'
	var dollar2 = '$2.5'
	
	document.write(Number(num) + '<br>'); // string을 number로
	document.write(parseInt(num) + '<br>'); // string을 number로

	document.write(Number(won) + '<br>'); // NaN
	document.write(parseInt(won) + '<br>'); // 1000; 문자가 나오기 전까지의 숫자를 추출; 모든 .을 문자로 간주
	document.write(parseInt(won2) + '<br>'); // NaN; 문자가 가장 앞에 있는 경우 숫자 추출 실패
	document.write(parseInt(won3) + '<br>'); // 10

	document.write('--------<br>');

	document.write(Number(num2) + '<br>'); // string을 number로
	document.write(parseFloat(num2) + '<br>'); // string을 number로
	
	document.write(Number(dollar) + '<br>'); // NaN
	document.write(parseFloat(dollar) + '<br>'); // 1.5; 문자가 나오기 전까지의 숫자를 추출; 첫 번째로 등장하는 .은 소수점으로 간주
	document.write(parseFloat(dollar2) + '<br>'); // NaN; 문자가 가장 앞에 있는 경우 숫자 추출 실패

	document.write('--------<br>');
	
	var no1 = '10';
	var no2 = '3.67';
	
	document.write(parseInt(no2) + '<br>'); // 3; 소수점 이하 자리 절사
	document.write(parseFloat(no1)); // 10
</script>
</head>
<body>

</body>
</html>

다음으로