성장, 그리고 노력

부족하더라도 어제보다 더 잘해지자. 노력은 절대 배신하지 않는다.

Javascript

Javascript Function

제이콥(JACOB) 2019. 12. 30. 23:11

자바스크립트의 함수에 대한 주제가 많이 있으나, 오늘은 간단하게만 정리해보려고 한다.

ECMAScript 5 까지의 함수

함수는 new 연산자와 함께 호출하거나 new 없이 호출하는 방법이 있다.

 위 코드에서 보다시피, new 연산자와 함께 호출하면 함수 내부의 this 값은 새로운 하나의 객체이고 그 객체를 반환한다. 반면 new 없이 호출하면 undefined를 반환한다. 그럼 사용자가 new 연산자를 이용하도록 어떻게 강제했을까? 가장 흔한 방법은 instanceof를 사용하는 거다.

// instanceof Syntax
object instanceof constructor
// object: 판별할 객체
// constructor: 판별한 함수
function Person(name) {
    if (this instanceof Person) {
        this.name = name;
    } else {
        throw new Error("Please use new!");
    }
}

const person1 = new Person("jacob"); 
const person2 = Person("jacob"); // 에러 발생!

 위 코드는 instanceof로 this 값을 사용하여 인자가 생성자의 인스턴스인지를 확인하는 함수다. 하지만 this가 new를 사용하지 않고 Person의 인스턴스가 될 수 있기 때문에 완벽한 방법은 아니다. 바로 call() 또는 apply()를 이용하는 것이다.

function Person(name) {
    if (this instanceof Person) {
        this.name = name;
    } else {
        throw new Error("Please use new!");
    }
}

const person1 = new Person("jacob"); 
const person2 = Person.call(person1, "jacob"); // 정상 실행

자바스크립트 함수에는 Call Construct라는 두 가지 내부 전용 메서드가 있다. (물론 다 있지는 않고 화살표 함수는 없다. 그래서 new로 호출할 수도 없다.). 함수를 new 없이 호출할 때는 함수를 실행하는 Call 메서드가 실행된다. 그리고 new로 호출할 때는 Construct 메서드가 호출된다. Construct의 개념은 우리가 자바에서 사용하던 생성자의 개념이다. 인스턴스를 만들어서 this에 할당하고 함수를 실행하는 역할을 한다. 

이렇게 함수의 두 얼굴 때문에 이 부분을 개선하게 된다.

 

ECMAScript 6 에서의 함수

객체가 아닌 프로퍼티로, 연산자의 실행 대상에 관련된 부가정보를 제공하는 new target 메타 프로퍼티가 추가 되었다. Construct 메서드가 호출될 때 new.target에는 new 연산자의 실행 대상(객체의 인스턴스)이 할당된다. 만약 Call이 실행되면 new.target은 undefined이다.

function Person(name) {
    if (typeof new.target !== "undefined") {
        this.name = name;
    } else {
        throw new Error("Please use new!");
    }
}

const person1 = new Person("jacob");
const person2 = Person.call(person1, "jacob"); // 에러 발생!

Person 생성자가 new 없이 생성될 때만 정확하게 에러를 발생시킨다. 

반응형