자바스크립트 생성자 함수

자바스크립트는 ‘생성자 함수’에 인스턴스에 만들어질 속성과 메서드를 정의하고, ‘생성자 함수’를 이용해서 인스턴스를 생성할 수 있다.

function Person(name) [
    this.name = name;
}

Person은 생성자 함수이다. 자바스크립트의 함수는 반복되는 로직을 모아놓은 함수가 될 수도, 인스턴스의 모양(속성이나 메서드)이 정의된 생성자가 될 수도 있다. 다른 언어에서는 클래스와 생성자가 구분되지만, 자바스크립트에서는 생성자 함수가 클래스의 역할을 한다. 그리고 생성자 함수의 이름은 Person처럼 첫 글자를 대문자로 쓰는 것이 관례이다.

인스턴스를 만들 때는 new 연산자와 함께 생성자를 호출한다.

var tarzan = new Person('Tarzan');
tarzan.name; // 'Tarzan'

주의할 것은 new 연산자가 빠지면 안되는 점이다. 그냥 Person() 으로 호출하면 Person은 일반 함수로서 동작한다. 일반 함수의 this는 기본적으로 글로벌 객체를 참조하며 strict-mode에서는 undefined이 된다.

이어서 메서드의 정의는 생성자 안에서 할 수도 있다. 하지만 비효율적이다.

function Person(name) {
    this.name = name;
    this.describe = function() {
        return 'my name is ' + this.name;
    }
}

new 연산자는 생성자의 this가 새로운 인스턴스를 가르키게 한다. 그리고 this로 참조하는 인스턴스에 속성과 메서드를 추가할 것이다. 위의 예제에서도 Person으로 생성하는 모든 인스턴스에서 name 속성과 describe 메서드를 추가한다. 그런데 name 속성은 인스턴스마다 모두 달라서 인스턴스에 추가되는 것이 맞지만, describe 메서드는 모든 인스턴스에 추가될 필요가 없다. 한 공간에 메서드를 한번만 정의하고, 모든 인스턴스에서 그 공간을 참조할 수 있게 하는 방법이 더 효율적이다.

function Person(name) {
    this.name = name;
}

Person.prototype.describe = function() {
     return 'my name is ' + this.name;
}

var tarzan = new Person('tarzan');
var jane = new Person('jane');

tarzan.describe(); // 'my name is tarzan'
jane.describeS(); // 'my name is jane' 

Person.prototype  객체에 메서드를 추가하면 모든 인스턴스에서 메서드를 공유할 수 있다. 

프로토타입

자바스크립트의 원시 값을 제외한 모든 객체는 코드 상에서 접근할 수 없는 내부 속성인 [[Prototype]] 속성을 가진다. [[Prototype]] 속성은 자신의 프로토타입 객체를 가르킨다. 프로토타입 객체란 자신의 부모 객체를 말한다. 그리고 [[Prototype]] 속성으로 연결된 두 객체의 관계를 프로토타입 관계(혹은 상속 관계)라고 부르며, 하나 이상의 프로토타입 관계는 프로토타입 체인을 형성한다. 그리고 자식 객체에서 동일한 프로토타입 체인에 있는 부모 객체의 속성이나 메서드에 접근할 수 있다.

Person의 인스턴스인 tarzan과 jane에도 역시 [[Prototype]]속성이 있다. 그리고 생성자가 new 연산자와 함께 실행될 때, 새로운 인스턴스인 tarzan과 jane의 [[Prototype]]속성은  Person.prototype 객체를 참조하게 된다. 즉, 인스턴스와 Person.prototype 객체는 프로토타입 관계에 있다. 인스턴스에는 describe 메서드가 직접 선언되어 있지 않지만, 프로토타입 체인을 통해 Person.prototype의 describe 메서드에 접근할 수 있다.

Person.prototype은 이름만 봤을 때 Person의 프로토타입 객체로 착각하기 쉽다. Person의 프로토타입 객체는 생성자 함수이기 이전에 일반 함수이기 때문에 자바스크립트 내장 객체인 Function이며, Person.prototype은 Person 인스턴스들의 프로토타입 객체(인스턴스 프로토타입)이다.

참고

  • 악셀 라우슈마이어의 자바스크립트를 말하다
  • MDN - 객체 지향 자바스크립트 소개
  • 생활코딩 - 생성자와 new


'JavaScript' 카테고리의 다른 글

[JavaScript] Trailing Comma 번역자료  (0) 2017.10.02
[JavaScript] 변수 스코프  (0) 2017.04.13
[JavaScript] 배열 연결  (0) 2017.01.26
[JavaScript] 동등, 일치 연산자  (0) 2016.10.04

+ Recent posts