"생성 안할거야?"

Jinux·2022년 8월 28일
0

생성자를 생성자로 호출하지 않을 때 this의 처리 방법

this는 호출방법에 따라 this가 가르키는 대상이 달라집니다. 일반함수는 window, 혹은 node.js환경이라면 global를 가르키겠죠.

반면 생성자 함수로 호출된 함수는 크게 순서 세 가지를 따라 this는 새로 생성된 함수를 가르키게 동작합니다. 참고

문제는 자바스크립트에선 함수와 생성자 함수는 구분점이 없다는 것에 있습니다. 물론 잘알려진 컨벤션으로 생성자함수는 대문자로 시작하게 네이밍한다는 규칙은 있지만요.

만약 생성자 함수로 작성한 함수를 그냥 함수로 잘못 호출할 경우를 대비할 수 있다면 좋지않을까요?

먼저 회피하는 로직을 보기전에 알아야할 지식이 있는데요. 참고 간단히 설명하자면 arguments.callee는 호출된 함수의 이름을 나타냅니다.

이 예제의 경우 A로 표기하여도 문제없이 동작하지만 특정함수의 이름과 의존성을 없애기 위해서 arguments.callee를 사용하는 것이 좋다고 합니다.

function A(arg) {
  if (!(this instanceof arguments.callee)) {
    return new arguments.callee(arg);
  }

  // 프로퍼티 생성과 값의 할당
  this.value = arg ? arg : 0;
}

var a = new A(100);
var b = A(10);

console.log(a.value);
console.log(b.value);

마무리

주의할점이 있는데요. callee의 경우 ES5의 strict 모드에 금지되었다고 합니다.
그 이유를 간단히 살펴보자면 두 가지가 있습니다. 초기 버전의 JavaScript에선 유명(named) 함수 식을 허용하지 않았습니다.

그때의 자바스크립트에선 재귀적으로 자기자신을 호출할 수 없었고 이를 우회적으로 callee를 사용하였다고 합니다.

시간이 흘러 유명함수 식이 업데이트 되었고, arguments.callee.caller 또는 Function.caller의 등장도 금지가 된 이유입니다. 자세한 내용을 알고 싶으시다면 mdn을 참고해주세요.

0개의 댓글