객체 리터럴 패턴이나 내장 생성자 함수를 쓰지 않고, 직접 생성자 함수를 만들어 객체를 생성할 수 있다.
1 2 | var adam = new Person("Adam"); adam.say(); // "I am Adam" | cs |
이런 형태는 객체지향 언어에서 클래스를 사용하여 객체를 생성하는 방식과 상당히 유사하다. 그러나 문법은 비슷해도 자바스크립트에서는 클래스라는 것이 없으며 위의 예제의 Person은 그저 보통 함수일 뿐이다.
아래 예제는 Person의 함수이다.
1 2 3 4 5 6 | var Person = function (name){ this.name = name; this.say = function(){ return "I am " + this.name; }; }; | cs |
new와 함께 생성자 함수를 호출하면 함수 안에서 다음과 같은 일이 일어난다.
- 빈 객체가 생성된다. 이 객체는 this라는 변수로 참조할 수 있고 해당 함수의 프로토타입을 상속받는다.
- this로 참조되는 객체에 포로퍼티와 메서드가 추가된다.
- 마지막에 다른 객체가 명시적으로 반환되지 않을 경우, this로 참조된 객체가 반환된다.
아래 예제는 이면에서 진행되는 부분을 주석으로 표기한 것이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | var Person = function (name){ // 객체 리터럴로 새로운 객체를 생성한다. // var this = {}; // 프로퍼티와 메서드를 추가한다. this.name = name; this.say = function(){ return "I am " + this.name; }; // this를 반환한다. // return this; }; | cs |
위의 예제에서 간단히 say()라는 메서드를 this에 추가했다. 결과적으로 new Person()을 호출할 때마다 메모리에 새로운 함수가 생성된다. say()라는 메서드는 인스턴스별로 달라지는 게 아니므로(재사용되는 멤버) 이런 방식은 비효율적이다. 이런 경우 Person의 프로토타입에 추가하는 것이 더 낫다.
1 2 3 | Person.prototype.say = function(){ return "I am" + this.name; } | cs |
추가 적으로 생성자의 반환 값에 대해 알아보겠다.
생성자 함수를 new와 함께 호출하면 항상 객체가 반환된다. 기본값은 this로 참조되는 객체다. 생성자 함수 내에서 아무런 프로퍼티나 메서드를 추가하지 않았다면 '빈'(즉 생성자의 프로토타입에서 상속된 것 외에는 '비어 있는') 객체가 반환될 것이다.
함수 내에 return문을 쓰지 않았더라도 생성자는 암묵적으로 this를 반환한다. 그러나 반환 값이 될 객체를 따로 정할 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | var Objectmaker = function(){ // 생성자가 다른 객체를 대신 반환하기로 결정했기 때문에 // 다음의 'name' 프로퍼티는 무시된다. this.name = "This is it"; // 새로운 객체를 생성하여 반환한다. var that = {}; that.name = "And that's that"; return that; }; // 테스트 var o = new Objectmarker(); console.log(o.name); // "And that's that" | cs |
위의 예제에서 볼수 있듯이 어떤 객체라도 (객체이기만 하면) 반환할 수 있다. 객체가 아닌 것 (예를 들면 문자열이나 false, ture)을 반환하려고 시도하면, 에러가 발생하진 않지만 그냥 무시되고 this에 의해 참조된 객체가 대신 반환된다.
'JavaScript & TypeScript' 카테고리의 다른 글
npm options --save (0) | 2022.05.02 |
---|---|
[javascript] new 연산자 (0) | 2016.02.23 |
[javascript] 객체 리터럴 (0) | 2016.01.21 |
[javascript] for문 사용법(최적화) (0) | 2016.01.13 |
[jQuery] Add함수를 이용한 확장집합 만들기 (0) | 2014.07.02 |