객체로서의 함수와 기명함수 표현식

파랑·2021년 8월 19일
0

모던 자바스크립트 정리본입니다. 객체로서의 함수와 기명함수 표현식 보러가기

  • javascript에서 함수는 객체이다.
  • 함수에 프로퍼티 추가, 제거, 참조를 통한 전달 가능

함수만의 프로퍼티

  • name : 함수 객체만의 이름이 있다 ( 자동 부여 -- contextual name)

    • 단 객체 메서드의 경우에는 자동 부여되지 않는다.
  • length: 함수 매개변수의 개수 반환

    • type introspection에 사용될 때도 있다.

    • 다형성(polymorphism)에 사용

      ex)

        // 인수의 종류에 핸들러를 다르게 처리
        function ask(queestion, ...handlers){
            let isYes = confirm(question);

            for(let handller of handlers){
                if(handler.length == 0){
                    if(isYes) handler();
                } else {
                    hanlder(isYes);
                }
            }
        }
        // 긍정적인 경우 핸들러 2개, 부정적인 경우는 핸들러 1개만
        // 긍정적인 대답 : (인수가 없는 핸들러 사용)
        // 응답에 상관없이 사용할 핸들러
        ask("질문 있으신가요", () => alert("OK 선택"), result => 	alert(result));

커스텀 프로퍼티

function sayHi(){
    alert("Hi");

    //함수 프로퍼티
    sayHi.counter++;
}
//함수 외부에서 초기화
sayHi.counter = 0;

sayHi();
sayHi();

alert(`호출횟수 : ${sayHi.counter}`)
  • 이는 클로저와 거의 유사

  • 그러나 클로저 사용 시,

    클로저에서 사용하는 변수는 함수 내부에서만, 함수 프로퍼티는 외부에서 변경이 가능함.

function sayHi(){
    //클로저 사용 시 함수 내부에서만 count 접근 가능
    //let count = 0;

    function() counter{
        return counter.counter++;
    }
    counter.count = 0;

    return counter;
}

let counter = makeCounter();

// 함수 외부에서 count 접근 가능
counter.count = 10;

이름이 있는 함수와 사용할 때의 장점

  • 함수 표현식 내부에서 자기 자신을 참조 가능

    • 외부 렉시컬 환경에서 찾지 않아도 됨.

    • 외부에서 변경 시 영향 받지 않음

      ex) sayHi이 사라지게 되면 welcome 안의 sayHi를 호출하지 못함

    let sayHi = function func(who) {
      if (who) {
        alert(`Hello, ${who}`);
      } else {
        sayHi("Guest"); // TypeError: sayHi is not a function
        func("Guest"); // 함수 지역 수준에 있기 때문에 외부 렉시컬에서 안 찾아도 됨.
      }
    };

    let welcome = sayHi;
    sayHi = null;

    welcome(); // 중첩 sayHi 호출은 더 이상 불가능합니다!
    ```

****응용****

- 나의 답안

```javascript
// 모두 함수 프로퍼티로 만들어서 사용함
function makeCounter() {
  function counter() {
    let newctn = counter.count;
    counter.count++;

    return newctn;
  }

  counter.count = 0;
  counter.set = function (value) {
    counter.count = value;
  };
  counter.decrease = function () {
    counter.count--;
  };

  return counter;
}
  • 모법 답안
//count는 클로저, set과 decrease 메서드는 함수 프로퍼티 사용
function makeCounter() {
  let count = 0;

  function counter() {
    return count++;
  }

  counter.set = (value) => (count = value); // 내부 렉시컬이 없고 외부에서 받아옴

  counter.decrease = () => count--;

  return counter;
}

0개의 댓글