본문 바로가기

JavaScript

[JavaScript] new.target

new.target 프로퍼티를 사용하면 함수가 new와 함께 호출되었는지 아닌지를 알 수 있습니다.

일반적인 방법으로 함수를 호출했다면 new.target은 undefined를 반환합니다. 하지만 new 와 함께 호출한 경우에는 new.target은 함수 자체를 반환합니다. new.target은 객체.속성명으로 되어있지만 new는 실제 객체는 아닙니다. MDN에 따르면 new는 가상 문맥이고, new.target속성은 모든 함수가 이용할 수 있는 메타속성이라고 합니다.

 

function User() {
  alert(new.target);
}

// 'new' 없이 호출함
User(); // undefined

// 'new'를 붙여 호출함
new User(); // function User { ... }

 

함수 본문에서 new.target을 사용하면 해당 함수가 new와 함께 호출되었는지(in constructor mode) 아닌지(in regualr mode)를 확인할 수 있습니다.

 

function User(name) {
  if (!new.target) { // new 없이 호출해도
    return new User(name); // new를 붙여줍니다.
  }

  this.name = name;
}

let bora = User("이현진"); // 'new User'를 쓴 것처럼 바꿔줍니다.
alert(bora.name); // 이현진

 

클래스에서는 어떻게 쓰이는지도 알아봅시다.

 

class Person {
    constructor() {
        console.log(new.target);
        console.log(new.target.name);
    }
}

const hyunjin = new Person() 
//class Person {
//    constructor() {
//        console.log(new.target);
//      console.log(new.target.name);
//    }
//}
// Person // (new.target.name)

클래스는 new 연산자 없이 호출이 불가능합니다. 따라서 클래스를 인스턴스화 하려면 new를 무조건붙여야 합니다.
클래스는 함수와 다르게 new연산자 없이는 호출이 불가능하기 때문에 new를 사용했을 때 new.target의 값에만 주목할 수 있습니다. new.target을 사용하면 인스턴스화된 클래스 자신을 반환합니다.

new.target의 활용

그렇다면 new.target을 어떻게 활용할 수 있을까요? new를 쓰지 않고 함수를 호출했을 때 그것을 방지하도록 막을 수 있습니다.

export default function PostList() {
    if (!new.target) {
        throw 'new 연산자를 사용해서 호출해주세요!'
    }
}

라이브러리를 분석하다보면 위와 같은 방식이 쓰인 것을 발견할 때가 있습니다. 이런 방식을 사용하면 new를 붙여서 함수를 호출하든 아니든 코드가 동일하게 동작하기 때문에 좀더 유연하게 코드를 작성할 수 있습니다. 그런데 이 방법을 믿고 객체를 만드는 경우에도 new를 생략하면 코드가 정확히 무슨일을 하는지 알기 어렵습니다. new가 붙어있으면 새롭운 객체를 만든다는걸 누구나 알 수 있기 때문에 new를 생략해서 객체를 만드는 것은 정말 필요한 경우에만 사용하고 남발하면 안됩니다.

참고

  • Modern JavaScript Tutorial

'JavaScript' 카테고리의 다른 글

함수와 일급 객체  (0) 2022.05.25
[JavaScript] Nullish Coalescing  (0) 2022.05.19
[Core JavaScript] VariableEnvironment & LexicalEnvironment  (0) 2022.03.06
[JavaScript] fetch  (0) 2022.03.04
[Core JavaScript] class  (0) 2022.03.04