JavaScript

자바스크립트 - 함수(내부, 재귀, 리턴, 콜백, 크로져)

jyeeee 2022. 5. 6. 17:00

1. 내부 함수

- 함수 내의 함수

- 지역 변수 처럼 지역 함수임으로 외부에서 쓰일 수 없다.

<script type="text/javascript">
		var myFn = function(){
			var sumFn = function(){
				console.log('내부 익명 함수');
			}
			function sumFn2(){
				console.log('내부 일반 함수');
			}
			sumFn(); //내부 함수 실행
			sumFn2(); //내부 함수 실행
			console.log('함수 실행');
		}
		myFn();
		// sumFn(); 내부 함수는 밖에서 호출 불가능
		// sumFn2(); 내부 함수는 함수 외에서 호출 불가능		
</script>
 

 

2. 재귀 호출

- 함수 내부 자신 함수를 호출 하는 것(자신을 호출하는 것)

· 외부에서 호출

· 내부에서 나 자신 호출

- 어떤 상황에서 쓰일까? 다섯개의 배열을 받는다?

· 조건식(true, false)를 쓰지 못할 경우 재귀호출

· 코드가 길어질 때

<script type="text/javascript">
		var callFn=function(n){
			console.log('callFn');
			/*
				조건 처리를 하여 재귀호출을 특정 시점에 중단해야 한다.
			*/
			if(n > 10){
				return ;
			}
			callFn(++n);//자신 함수를 호출
		}
		callFn(0);		
	</script>
 

 

3. 리턴 있는 재귀 호출

<script type="text/javascript">
		function fnA(){
			return fnB();
		}
		function fnB(){
			return fnC();
				} 
		function fnC(){
			return 10;		
		} 
		console.log(fnA());
		
		function fnCall(n){
			if(n>10){
				return n;
			}else{
				return  fnCall(++n);
			}			
		}
		console.log(fnCall(0));
	</script>
 

4. 콜백 함수

- 이벤트 및 특정 시점으로 인해 후에 시작되는 함수

- 주로 비동기 방식이다.

- 후에 시작되는 함수는 매개변수로 데이타를 받을 수 있다.

<script type="text/javascript">
		//코드는 위에서 아래로 실행
		function fn01(){
			return 1;
		}
		var result=fn01();
		console.log(result);
		
		//반복문 종류 후 아래 코드 실행
		for(var i=0; i<10; i++){
			console.log('반복문')
		}
		console.log('반복 종료');
		
		/*
			setTimeout -> 내장 함수
			- 1번째 인수 함수
			- 2번째 인수 숫자(시간)
			- 2번째 인수에 해당되는 시간 후에 1번째 인수 함수 실행
			* 1000 -> 1초
		*/
		setTimeout(function(){ // 함수를 저장해 놓았다가 특정 시점 발생시 함수 실행
			console.log('3초 후 실행');
		},3000)
		console.log('코드 실행 종료');
			
		/*
			콘 솔 출력 결과
			- 코드 실행 종료 // 동기화 -> 순차적으로 코드 실행
			- 3초 후 실행 // 특정 시점 이후에 실행
		*/
		var cnt=0;
		for(var i=0; i<10; i++){
			console.log('반복실행',i);
			setTimeout(function(){
				cnt++;
				// 실행 시점이 다른 데이터는 순차적으로 실행되는 코드에서 데이터를 갱신 할 수 없음
				console.log(cnt,'setTimeout');
				// 실행 시점이 다른 데이터는 다른 함수로 데이터 전달 해서 주로 사용된다.
				callFn(cnt);
			},1000);
		}
		console.log(cnt,'cnt');
	
		function callFn(n){
			console.log(n,'후 데이터 받기');
		}
	</script>
 
<script type="text/javascript">
		/* function myFn(fn){			 
			fn(1);			 
		}
		
		myFn(function(n){
			console.log('myFn',n);
		}) */

		/*
			인자로 함수를 받는 이유는?
			함수 내부에서 실행 시 점이 언제인지를 모르기 때문에
			함수에 코드를 저장했다가 
			시점 발동시 인자로 들어온 해당 함수를 실행
		*/
		
		function myFn(fn){//1.함수 선언	
			//3. 인자로 함수 받았음으로 함수 실행
			fn(1);			 
		}
		
		var mfn=function(n){ //4. 함수를 실행 했음으로 매개변수로 인자값 받기
			console.log('myFn',n);
		}
		
		myFn(mfn); //2.함수 실행시 인수로 함수 전달
		
		myFn(function(n){ 
			console.log('다른코드');
		});
		
		
		var userName ='';
		function callFn01(fn){
			/*
				사용자가 5초 후에 실행 했다는 가정
				혹은 서버에 5초 후에 응답 했다는 가정
				5초 후 응답 데이터를 '홍길동'이라는 문자열을 전달
			*/
			setTimeout(function(){
				userName='홍길동'; //userName에 5초 후에 저장은 가능
				fn('홍길동');
			},5000);
		}
		/*
			비동기화로 작동되는 함수는 데이터 전달을 콜백 함수로 함
		*/
		callFn01(function(name){ //5초 후에 반응할 함수를 전달
			console.log(name,'콜백 데이터');
		});
		console.log(userName,'순차적 실행');
	</script>
	
	<h2>이벤트 예제</h2>
	<button type="button" onclick="myEv('홍길동')">클릭</button>
	
	<script type="text/javascript">
		var myName='';
		function myEv(msg){
			console.log(msg);
			myName=msg;
		}
		console.log(myName);
	</script>
 

5. 크로져

- 실행된 함수의 주위 환경을 기억하고 있다.

<script type="text/javascript">
		function fn01(){
			var n1=10; // 지역변수 외부에서 접근 불가
			return function(){
				console.log('리턴되는 함수');
				return n1;
			}
			
		}
		var fn=fn01();
		console.log(fn); //리턴된 값이 함수 코드
		var n = fn(); //함수 임으로 실행 가능
		/*
			함수가 실행이 되면 주위의 지역 변수를 기억하고 있어
			값에 접근이 가능하다.
		*/
		console.log(n);
	</script>
 
<script type="text/javascript">
		
		for (var i=0;i<10;i++){
			setTimeout(function(){
				//i값은 이미 10으로 갱신된 상태이며, 1초 후에 갱신된 값을 출력
				console.log(i,'setTimeout에서 i출력')
			},1000);
		}
		console.log(i,'반복문 초기값');
		
		
		
		
		
		var myN=function(i){
			setTimeout(function(){ // i값을 함수로 감싸면, 반복하여 출력된다. 전역변수는 끌어다 쓸 수 있다.
				console.log(i,'setTimeout2에서 i출력')
			},1000);
		}	
		for (var i=0;i<10;i++){
			myN(i);
		}
		
		
		
		
		for (var i=0;i<10;i++){
			/* 
				익명함수를 () 내부에서 선언가능 -> 코드 저장
				(function(){}) 
				(function(매개변수){})(인수) -> 익명함수 바로 실행
			*/
			(function(n){
				setTimeout(function(){
					//i값은 이미 10으로 갱신된 상태이며, 1초 후에 갱신된 값을 출력
					console.log(n,'setTimeout3에서 i출력')
				},1000);
			})(i);			
		}
	</script>