본문 바로가기
FrontEnd/Javascript

[JS] Javascript의 함수(Function)

by pplucy 2021. 1. 21.

* Template literals : 문자열을 보다 편리하게 사용할 수 있도록 템플릿을 제공해준다.

   - 사용법 : `(백틱) 을 사용해 문자열을 감싸준다. ex. `str`

 

   1) 여러줄의 문자열을 편리하게 사용하기 위해 사용한다, 템플릿 리터럴을 사용하지 않으면 라인피트를 사용해 줄바꿈 처리를 해주고

      문자열 결합 연산자도 신경을 써야 하지만 template literals를 사용하면 그럴 필요가 없다.

 

   2) ${}을 사용하기

     let strVal = 'template literals';

     console.log( "이전  : " + strVal + "라는 것이다.");

     console.log( `이후 : 이건 ${strVal} 라는 것이다.`); --> 더 깔끔하게 표현가능 !

 

 

Function

: 자바스크립트에서 function은 ocject로 간주된다.( 변수에 할당, 파라미터로 전달 가능, 함수를 리턴 가능)

: 자바스크립트에선 함수의 타입이 존재 하지 않는다.

 

lexical scope

   Lexical Scope : 함수를 선언하는 시점에 따라서 상위 스코프가 결정되는 것

   Dynamic Scope : 함수가 설정되는 시점에 따라서 상위 스코프가 결정되는 것

 

   : 함수 내부에서 상위스코프(함수보다 먼저 생성되고 늦게 소멸되는) 변수에는 접근할 수 있지만

     하위 스코프(함수보다 늦게 생성되고 빨리 소멸되는) 변수에는 접근할 수 없다,

     만약, 상위스코프에 같은 이름의 변수가 존재하면, 가까운 스코프의 변수를 사용하게 된다.

 - Lexical Scope 

   함수가 호출되는 시점이 아니라 선언되는 시점의 상위 스코프를 탐색하기 때문에, inner() 함수 내부에서 선언된 변수는

   그 어디서도 사용하지 않게된다.

   또한 inner() 함수가 outerScope() 함수, innerScope()함수를 호출하게 되는 아래와 같은 상황에서

   outerScope는 함수가 선언될 시점의  let val = 1; 을 따르게 되고, innerScope()함수는 이 함수가 선언될 시점에서의 let var = 2; / let var2 = 2;

   를 따르게 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<div id = 'scope-note' class='note' onclick='test()'></div>
    <script type="text/javascript">
         
        
    let val = 1// 전역변수
 
     function outerScope(){
         $('#scope-note').innerHTML += `<br>outerScope에서 출력되는 val 값은 ${val} 입니다.`;
     }
     
     function test(){
             
 
         let val = 2
         let val2 = 2;
             
         function innerScope(){
             $('#scope-note').innerHTML += `<br>innerScope에서 출력되는 val 값은 ${val} 입니다.`;
             $('#scope-note').innerHTML += `<br>innerScope에서 출력되는 val2 값은 ${val2} 입니다.`;
         }
             
         function inner(){
             let val = 3// 이 코드는 사용하는 곳이 없는 상태인 것
             let val3 = 3// 이 코드는 사용하는 곳이 없는 상태인 것
             outerScope();
             innerScope();
             
         }

         inner();
     }
         
cs

 

 

 

 

함수표현식

: 함수를 값으로 다루는 방식

: 특징

  1) 함수를 변수에 담을 수 있다.

  2) 함수를 전달인자로 사용할 수 있다.

  3) 함수를 return 할 수 있다.*****

 

 (이 3가지 특징을 모두 충족하는 함수를 1급 객체라고 한다,)

 

 ===== 함수선언식 === 함수표현식 =====

함수선언식 : 일반적인 함수의 형태로 사용

function sum(a,b){

return a+b;

} //세미콜론을 붙이지 않음!

sum(); 

 

함수표현식 : 여기서 sum은 함수의 이름이 아니다,

                        익명함수를 sum이라는 변수에 담은 것

let sum = function(a,b) {

return a+b;

}

sum(); 

 =================================

 

   

 

 

- 익명함수를 변수에 담아보기

        let fn = function(){}

        사용시 :  fn();

         -> 함수표현식을 사용할 경우 함수가 선언되는 것이 아니라, 함수가 초기화 되는 것이기 때문에

              변수 호이스팅이 발생하지 않는다.

 

1
2
3
4
5
6
let functionExpression = function(){
             $('#expr-note').innerHTML += '함수 표현식 방식은 호이스팅 발생하지 않음';
             
         }
         
          functionExpression();
cs

 

 

 

- 익명함수를 화살표 함수로 작성하여 간단하게 표현해주기

   : 함수표현식의 단축방법

   (일반적인 익명함수 : let fn = function(args...){}; )

   (화살표 함수 : () => {}; )

      작성구문 

        1) 화살표 함수 : () => {}; 

        2) 만약, 매개변수가 하나라면 괄호()를 생략할 수 있다.

             ex) let number = function(num) >>> let number = num => {};

        3) 만약 함수에 return 문만 존재한다면 return 예약어와 중괄호{}도 생략할 수 있다.

             ex) let number =  function(num) { 

                                            return num + 1;

                                           };

                   >>> let number = num => num + 1; 

        4) 화살표 함수에는 변수가 정의되어있지 않다.            

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let arrowFunc1 = (name, age) => {
     if(age < 14){
          return `${name}씨는 어린이 입니다.`;
      } else {
          return `${name}씨는 청소년 입니다.`;
      }
}
     $('#expr-note').innerHTML += '<br> 화살표 함수로 간단하게 표현하였습니다.: ' + arrowFunc1('USER','27');
         
=========================================================================================================
let arrowFunc2 = (name, age) => {
     if(age < 14){
          return `어린이 입니다.`;        
      } else {
         return `청소년 입니다.`;
          }
}
    $('#expr-note').innerHTML += '<br> 화살표 함수로 간단하게 표현하였습니다.: ' + arrowFunc2(27);
    
=========================================================================================================        
let arrowFunc3 = name => `${name}씨 반가워요 ! `;
$('#expr-note').innerHTML += '<br> 화살표 함수로 간단하게 표현하였습니다.: ' + arrowFunc3('USER');
        
 
cs

 

=> 함수표현식 결과값들

 

 

 

 

즉시 실행 함수(IIFE : Immediately Invoked Function Expression)

  : 즉시실행함수란, 함수를 선언함과 동시에 실행되는 함수를 뜻한다.

    같은 함수를 다시 호출 할 수 없고 최초 한 번만 실행되어야 하는 초기화 코드에 많이 사용한다.

 : 함수를 괄호()안에 담고 ()를 다시 붙여준다.

1
2
3
4
5
6
7
8
9
10
11
12
(function() {
    $('#iife-note').innerHTML += '함수가 즉시 실행된다.<br>';        
 
})();
        
=======================================================================        
        
(() => {
    $('#iife-note').innerHTML += '화살표 함수로 확인 : 함수가 즉시 실행된다.<br>';    
 
})();
        
cs
1
2
3
!function() {
            $('#iife-note').innerHTML += '오잉? 논리부정연산자를 붙였더니 함수가 즉시 실행 된다.<br>';        
        }();
cs

 

함수를 return 하기

: #return-note에 onclick이 발생하면 testReturn()함수를 호출 !

: 누를 때마다 함수가 호출이 되기 때문에 return 값이 누적되서 출력된다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<div id = 'return-note' class = "note" onclick = "testReturn()"></div>
<script type="text/javascript">
 
function returnOuterFn(){ 
   return function(arg){
               return '안쪽 함수가 반환됩니다. 안쪽 함수의 매개변수 ' + arg + '을 전달 받았습니다.'
            };
}
            
function testReturn(){
    let outerFn = returnOuterFn();
                
    $('#return-note').innerHTML += `arg 1 전달 :  ${outerFn(1)}`;
//$('#return-note').innerHTML += `arg 1 전달 :  ${returnOuterFn()()}`;
                
}
cs

-> onclick * 2

 

Closure

 : 이미 실행이 끝난 함수의 지역변수를 참조할 수 있게끔 해주는 함수를 Closure라고 한다.

 : 아래의 testClosure() 함수의 z변수에 담긴 익명함수는 이 함수가 생성될 때 상위 스코프가 정해지게 된다.

   (상위 스코프 -> x, y)

 

(예시1)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<div id='closure-note' class = 'note'></div>
<script type="text/javascript">
            
    function testClosure(arg){
                
        let x = 'testClosure의 지역변수 x의 값 : ';
        let y = arg;
        let z = function(){
                y++;
                return x + y;
        }
                
        return z; // testClosure()함수의 리턴값이 z, 이때 이 z를 즉, 익명함수를 실행하기 위해서는 x,y값이 있어야 함
                          // 이때 x,y값은 상위 스코프 체인의 값을 참조하게 되는 것.
                          // 그렇기 때문에 이 함수가 돌아가야 할 상황들을 대비해서 x,y값이 스코프체인에 저장된 채로 있기 때문에
                          // 함수는 실행컨텍스트에서는 내려가더라도 값이 저장되어 있는 것
    }
            
    let testFn = testClosure(0);
    for(let i = 0; i < 5; i++){ // 반복할 때마다 함수는 끝나는데 왜 y가 증가하느냐?
                               // 변수가 선언된 testClosure가 끝났음에도 불구하고 메모리에서 내려가지 않았다는 뜻 !
                                // 어떻게 이럴 수 있느냐 ? testClosure()가 실행컨텍스트에서는 내려가지만
                                // testFn()의 스코프체인에 testClousre의 변수 객체가 살아있기때문에 x, y도 살아있게 되는 것

document.querySelector('#closure-note').innerHTML += `${testFn()}<br>`;
document.querySelector('#closure-note').innerHTML += `${testClosure(i)()}<br>`;
-> 함수를 불러내는 방법2 (함수안의 함수라 괄호2개)
    }
            
cs

 

-> 계속 증가되는 y값을 볼 수 있음

 

 

 

 

 

(예시2)

1
2
3
4
5
6
7
8
9
10
11
12
13
<div id= 'test-note' class='note'></div>
<script type="text/javascript">
 
    let arr = [];
    for(let i = 0; i < 6; i ++){
        arr[i] = function(){
            return i;    
        }    
    }
    //이미 closure
    arr.forEach((v) => {
document.querySelector('#test-note').innerHTML += `${v()}<br>`;
    })
cs

 

 

 

Call back 함수

: 콜백함수란, 특정 이벤트가 발생한 후 , 수행될 함수를 의미

  보통 이벤트를 발생시킬 함수의 매개변수로 콜백함수를 전달하면

  이벤트가 발생한 후 해당 함수에서 내부적으로 콜백함수를 호출하는 방식으로 동작

: addEventListener 의 콜백함수의 첫번째 매개변수(e)로는 발생한 이벤트 객체가 넘어오게 된다.

  매개변수로 전달되어지는 event 객체의 target을 사용해 이벤트가 발생한 요소의 document object로 접근할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div id ='callback-note' class ='note'></div>
<script type="text/javascript">
    
document.querySelector('#callback-note').addEventListener('click'// click이벤트가 발생했을때 콜백함수를 불러줄 것이다.
 
        (e) => {
                e.target.style.backgroundColor = 'maroon';     

/*() => {
document.querySelector('#callback-note').target.style.backgroundColor = 'maroon'; });
-> 이벤트 객체가 넘어와 이렇게 되는 것 !!! */

 });
        
/*
    $('#callback-note').onclick = (e) => {
                e.target.style.backgroundcolor = 'red'; // 이 방법보다는 callback함수 방법 이용 선호
                    
                }); */
        
</script>
 
cs

 

-> div의 backgroundColor 가 maroon으로 바뀐 상태 !

'FrontEnd > Javascript' 카테고리의 다른 글

[JS] Javascript의 Promise  (0) 2021.01.22
[JS] Javascript의 비동기(asynchronous)  (0) 2021.01.22
[JS] Javascript의 배열(array)  (0) 2021.01.19
[JS] Javascript의 statement  (0) 2021.01.19
[JS] Javascript 의 연산자(operator)  (0) 2021.01.19

댓글