ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수 - Javascript 핵심 개념 | 정재남
    Javascript/ECMAScript 2009 (ES5) 2020. 3. 17. 23:23
    반응형

    [출처 : https://www.inflearn.com]

    1. 호이스팅

    ※ Hoist : (사전적 의미) 끌어 올리다. ⇒ 변수 '선언'과 함수 '선언'을 끌어 올린다.

     

    # 호이스팅 (Hoisting)

    : 호이스팅은 선언과 밀접한 관계가 있다. 자바스크립트 엔진은 코드를 실행하기 전 단계로 코드 전반에 걸쳐서 선언된 내용이 있는 지 훑어 보고 발견하는 족족 위로 끌어 올린다.

     

    # 왼쪽에 작성한 코드는 변수와 함수의 선언이 위로 올라가면서 자바스크립트 엔진이 실제로 실행할 코드는 오른쪽이 된다.

    console.log(a());                  function a() {
    console.log(b());                    return "a";
    console.log(c());                  }
    function a() {                     var b;                                   
      return "a";                      var c;              
    }                                  console.log(a());
    var b = function bb() {            console.log(b());
      return "bb";             ⇒      console.log(c());
    }                                  b = function bb() {
    var c = function () {                return "bb";
      return "c";                      }
    }                                  c = function() {
                                         return "c";
                                       }

    - 함수 선언문은 통째로 올라갔지만, 함수 표현식은 선언만 올라갔다. 할당은 호이스팅의 해당 사항이 아니다.

    - 함수 선언문은 그 자체로 하나의 선언이지만 함수 표현식은 선언과 할당이 한 문장에 이뤄진 것으로 분리가 가능하다.


    2. 함수선언문과 함수표현식

    # 함수선언문 (function declaration)

    function a() {
      return "a";
    }

    # 기명 함수표현식 (named function expression)

    var b = function bb() {
      return "bb";
    }

    # (익명) 함수표현식 (unnamed/annonymous function expression)   *익명 생략 가능

    var c = function () {
      return "c";
    }

    불과 얼마전 모던 브라우저 대부분이 익명 함수의 경우 네임 프로퍼피에 값을 부여하지 않았기에 디버깅 시 기명 함수표현식이 이점이 있었다. 어떤 함수에서 에러가 발생했을 때 에러가 발생한 함수의 이름을 콘솔에 출력해줬기 때문에 이름을 찾아서 오류를 해결하기 용이했다.

     

    하지만 최근 브라우저는 함수명이 비어있을 경우 자동으로 변수명을 네임 프로퍼티에 할당하기에 기명 함수표현식을 쓰는 경우가 줄어들었따.

     

    # 함수표현식이 선언되고 정의되는 방식    *위 익명 함수표현식 예제 코드 참고

    1. 변수 'c' 선언

    2. 익명함수 선언

    3. 변수 'c'에 익명함수를 할당

     

    # 함수 표현식의 개념 : 선언한 함수를 변수에 할당한다.

     

    # 함수 선언문과 함수 표현식의 차이는 할당 여부에 있다.

    할당을 하지 않으면 전체가 호이스팅의 대상이 되며, 할당을 하는 경우 함수는 그 자리에 남아 있고 변수만 호이스팅을 하게 된다.

     

    # 호이스팅이 중요한 이유

    : 코드가 복잡해지면서 서로 다른 줄에서 선언한 함수의 내용이 다를 경우, 호이스팅에 의해서 두 함수선언문 모두 맨 위로 끌어 올려지고 캐스케이딩 원칙에 의해서 나중에 호이스팅된 함수가 이전 함수를 덮어 씌우게 된다.

     

    # 호이스팅과 같은 여러가지 이유로 인해서 함수선언문보다는 함수표현식을 쓰는 것을 권장한다. ⇒ 안전하고 예측 가능한 소스를 위해서.


    3. 함수 스코프, 실행 컨텍스트

    # 스코프 (Scope)

    : 변수의 유효 범위

     

    # 실행 컨텍스트 (Execution Context)

    : 실행되는 코드 덩어리    *추상적 개념

     

    ※ 가장 큰 차이점은 스코프는 정의될 때 결정되며, 실행 컨텍스트는 실행될 때 생성된다.

     

    # 실행 컨텍스트에는 호이스팅, this 바인딩 등의 정보가 담긴다.

     *호이스팅 : 호이스팅이 이루어진 후의 함수 본문 내용

     *this 바인딩 : this가 무엇인지에 대한 정보, 함수 내부에서 this는 무엇이라고 연결해주는 것

    즉, 실행 컨텍스트란 사용자가 함수를 호출했을 때 내부적으로 해당 함수를 실행하기 위해서 필요한 정보들을 불러 모아 놓은 집합체.

     

    함수 스코프와 실행 컨텍스트의 이해

     


    4. 메소드

    # 함수와 메소드의 차이

    - 함수 앞에 속성접근자(점)가 있는 경우 메소드

    - this를 바인딩 여부. 메소드는 this를 바인딩 한다.    *이때 this는 메소드가 속한 객체

     

    메소드의 이해


    5. 콜백함수

    # call / back

    : something will call this function back sometime somehow

    ⇒ 무언가가 이(콜백) 함수를 어떤 방식인지, 언제 호출할 지 모르지만 실행해서 나에게 다시 돌려준다.

    - 콜백함수는 제어권을 넘겨준다(맡긴다)

    - 콜백함수를 어떻게 처리할 지는 제어권을 넘겨 받은 대상에게 달려 있다.

     

    예시-1. setInterval

    setInterval의 이해

    콜백함수의 제어권은 setInterval에게 넘겼다. setInterval은 1초마다 콜백함수를 실행하고 그 결과를 나에게 돌려준다.

     

    # setInterval의 콜백함수를 변수로 치환

    var cb = function(){
      console.log("1초마다 실행됩니다.");
    }
    
    setInterval(cb, 1000);

    # setInterval(callback, milliseconds) 의 MDN 정의 

    : milliseconds 단위마다 callback을 호출하는 함수

     

    예시-2. forEach()

     

    forEach의 이해

    # array.forEach(callback[, thisArg]) 의 MDN 정의   *[] 생략 가능하다는 메타표기법

    ㆍcallback : 각 요소에 대해 실행할 함수, 다음의 인수 셋을 취하는 :

      - currentValue : 배열에서 현재 처리 중인 요소

      - index : 배열에서 현재 처리 중인 요소의 인덱스

      - array : forEach()가 적용되는 배열

    ㆍthisArg[선택사항] : callback을 실행할 때 this로서 사용하는 값

     

    즉, forEach() 메소드의 콜백함수는 currentValue, index, array 순서대로 인자가 온다

     

    # Array.prototype.forEach() 메소드의 함수 내부를 구현하면 다음과 비슷하다.

    Array.prototype.forEach = function(callback, thisArg) {
      var self = thisArg || this;
      for(var i = 0; i < this.length; i++) {
        callback.call(this, this[i], i, self)
      }
    }

    콜백을 어떤 타이밍에, 어떤 형태로 호출하고 그 콜백에게 어떤 데이터를 매개변수로 넘겨줄 지에 대해서까지 forEach문 전체에서 자체적으로 규정하고 있다. 즉, 콜백함수에 어떤 인자들이 어떤 순서로 나열되어 호출될 지는 전적으로 forEach의 규칙을 따르게 된다.

    따라서 사용자는 forEach가 정의한 규칙대로 콜백함수를 정의해야만 원하는 결과를 얻을 수 있다.

     

    콜백함수를 정의할 때 파라미터의 순서는 제어권을 넘겨 받을 대상(ex. forEach)의 규칙을 반드시 따라야만 한다.

     

    예시-3. addEventListener()

    document.body.innerHTML = '<div id="a">abc</div>';
    function clickFunc(x) {
      console.log(this,x);
    }
    
    document.getElementById('a').addEventListener('click', clickFunc);
    // 제이쿼리
    $("#a").on('click',clickFunc);
    
    /* console 값
    <div id="a">abc</div>
    MouseEvent {isTrusted:true, screenX: 11, ...}   *마우스 이벤트
    */

    # target.addEventListener(type, listener[, useCapture]) 의 MDN 정의 

    ㆍtype : 등록할 event type을 나타내는 문자열

    ㆍlistener : 특정 타입의 이벤트가 발생할 때 알림을 받을 객체. 반드시 EventListener 인터페이스를 수행하는 객체이거나, Javascript function이어야 합니다. *일반적으로는 callback 함수

    * 콜백함수 내부에 대한 정의를 유추하면, this는 이벤트 타겟이며 콜백함수의 첫 번째 인자는 이벤트 객체일 것이다.

     

    # 콜백함수의 특징

     - 다른 함수(A)의 매개변수로 콜백함수(B)를 전달하면, A가 B의 제어권을 갖게 된다.

     - 특별한 요청(bind)이 없는 한 A에 미리 정해진 방식에 따라 B를 호출한다.

     - 미리 정해진 방식이란 this에 무엇을 바인딩할 지, 매개변수에는 어떤 값들을 지정할 지, 어떤 타이밍에 콜백함수를 호출할 지, 등

     

    *주의! 콜백함수는 함수다. 메소드가 아니다

     

    반응형

    댓글

Luster Sun