Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript new.target 메타 프로퍼티 완벽 이해하기

new.target은 JavaScript에서 함수 또는 생성자가 new 키워드와 함께 호출되었는지 여부를 런타임에 확인할 수 있도록 해주는 메타 프로퍼티(metaproperty)입니다.

일반적으로 생성자 함수는 반드시 new 연산자와 함께 호출되어야 의도대로 동작합니다. 그러나 실수로 new 없이 호출하면 this가 전역 객체를 가리키게 되어 예기치 않은 버그가 발생할 수 있습니다. 이때 new.target을 사용하면 이러한 상황을 감지하고 오류를 방지할 수 있습니다.

new.target의 동작 원리

  • 함수가 new 키워드로 호출되면, 함수 내부에서 new.target은 해당 함수 자체(생성자)를 참조합니다.
  • 함수가 일반적인 방식으로 호출되면, new.targetundefined가 됩니다.

이 특성을 활용하면 생성자 함수 내부에서 new 없이 호출된 경우 에러 메시지를 출력하거나, 자동으로 new를 붙여 다시 호출하는 방어 코드를 작성할 수 있습니다.

예제 코드

다음은 new.target을 사용하여 Student 생성자가 new 키워드 없이 호출되는 경우를 감지하는 예제입니다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
    body {
        font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
    }
    .result {
        font-size: 20px;
        font-weight: 500;
        color: blueviolet;
    }
</style>
</head>
<body>
<h1>JavaScript의 new.target</h1>
<div class="result"></div>
<br />
<button class="Btn">CLICK HERE</button>
<h3>위 버튼을 클릭하면 new 키워드 없이 Student 생성자가 호출됩니다</h3>
<script>
    let resEle = document.querySelector(".result");
    let BtnEle = document.querySelector(".Btn");
    function Student(name, age, place) {
        if (!new.target) {
            resEle.innerHTML = "Error : Student should be used with the new operator";
        }
        this.name = name;
        this.age = age;
        this.place = place;
    }
    BtnEle.addEventListener("click", () => {
        Student("Shawn", 22, "Delhi");
    });
</script>
</body>
</html>

실행 결과

페이지를 처음 열었을 때의 화면입니다.

JavaScript new.target 메타 프로퍼티 완벽 이해하기

'CLICK HERE' 버튼을 클릭하면 Student 함수가 new 키워드 없이 호출되므로, new.targetundefined가 되어 아래와 같이 에러 메시지가 화면에 표시됩니다.

JavaScript new.target 메타 프로퍼티 완벽 이해하기

추가 활용 팁

new.target은 ES6 클래스 생성자 내부에서도 사용할 수 있습니다. 클래스는 애초에 new 없이 호출하면 TypeError가 발생하지만, 상속 관계에서 부모 클래스의 생성자가 어떤 자식 클래스를 통해 호출되었는지 확인하는 용도로 활용됩니다.

class Animal {
    constructor() {
        console.log(new.target === Animal); // true 또는 false
    }
}
class Dog extends Animal {}

new Animal(); // new.target === Animal → true
new Dog();    // new.target === Dog → false

또한, new.targetundefined일 때 자동으로 new를 붙여 재호출하도록 처리하면, 사용자가 new를 빠뜨려도 안전하게 객체를 생성할 수 있습니다.