생성자란 new와 함께 호출될 뿐 별다를 것 없는 함수에 불과하다.
그렇다면 생성자를 호출할 때 new를 빼먹으면 어떻게 될까? 문법 오류나 런타임 에러가 발생하지는 않지만, 논리적인 오류가 생겨 예기치 못한 결과가 나올 수 있다. new를 빼먹으면 생성자 내부의 this가 전역 객체를 가리키게 되기 때문이다.
생성자 내부에 this.member와 같은 코드가 있을 때 이 생성자를 new 없이 호출하면, 실제로는 전역 객체에 member라는 새로운 프로퍼티가 생성된다. 이 프로퍼티는 window.member 또는 그냥 member를 통해 접근할 수 있다. 알다시피 전역 네임스페이스는 항상 깨끗하게 유지해야 하기 때문에 이런 동작 방식은 대단히 바람직하지 않다.
아래의 예제를 실행해보시면 정확하게 알 수 있을 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // 생성자 function Waffle(){ this.tastes = "yummy"; } // 새로운 객체 var good_morning = new Waffle(); console.log(typeof good_morning); // "object" console.log(good_morning.tastes); // "yummy" // 'new' 를 제외시 var good_morning = Waffle(); console.log(typeof good_morning); // "undefined" console.log(window.tastes); // "yummy" | cs |
해결책 두가지가 있다.
첫번째, 생성자가 항상 생성자로 동작하도록 해주는 방법이다.
this에 모든 멤버를 추가하는 대신, that에 모든 멤버를 추가한 후 that을 반환하는 것이다.
1 2 3 4 5 6 7 8 9 10 11 | function Waffle(){ var that = {}; that.tastes = "yummy"; return that; } function Waffle(){ return { tastes : "yummy"; }; } | cs |
위의 Waffle() 구현 중 어느 것을 사용해도, 호출 방법과 상관 없이 항상 객체가 반환된다.
1 2 3 4 | var first = new Waffle(), second = Waffle(); console.log(first.tastes); // "yummy" console.log(second.tastes); // "yummy" | cs |
위의 방법은 좋은 방법이지만 한가지 단점은 프로토타입과의 연결고리를 잃어버린다는 것이다. 즉, Waffle() 프로토타입에 추가한 멤버를 객체에서 사용할 수 없다.
두번째, 인스터스 객체 확인
생성자 내부에서 this가 해당 생성자의 인스턴스인지를 확인하고, 그렇지 않은 경우 new와 함께 스스로를 재호출하는 것이다.
아래 예제를 보면 한번에 이해가 갈 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | function Waffle(){ if(!(this instanceof Waffle)){ return new Waffle(); } this.tastes = "yummy"; } Waffle.prototype.wantAnother = true; // 호출확인 var first = new Waffle(), second = Waffle(); console.log(first.tastes); // "yummy" console.log(second.tastes); // "yummy" console.log(first.wantAnother); // true console.log(second.wantAnother); // true | cs |
'JavaScript & TypeScript' 카테고리의 다른 글
TypeScript에서 `==` 와 `===` 의 차이점 및 적절한 사용법 (0) | 2024.09.19 |
---|---|
npm options --save (0) | 2022.05.02 |
[javascript] 사용자 정의 생성자 함수 (0) | 2016.02.18 |
[javascript] 객체 리터럴 (0) | 2016.01.21 |
[javascript] for문 사용법(최적화) (0) | 2016.01.13 |