JavaScript

프로토타입

클래스 기반?

  • 자바스크립트에서는 모든 것이 객체인 객체 기반 언어라고 하였습니다.
    하지만 자바스크립트는 JAVA나 C++, Python 같은 일반적인 객체 지향 언어와의 차이점이 있습니다.
    가장 큰 차이점은 자바스크립트는 일반적인 객체 지향 언어에서 객체를 구성하기 위한 클래스의 개념이 없는 것입니다.

    일반적인 객체 지향 언어에서는 클래스를 선언하고 그 안에 생성자 함수를 생성하고 이를 이용하여 객체 인스턴스를 생성하지만, 자바스크립트에서는 클래스의 선언 없이 곧바로 생성자 함수를 통해 객체를 생성합니다.

 

 

 

프로토타입(Prototype)

  • 일반적인 객체 지향 언어들은 클래스를 통해 객체 지향 언어에서 나타나는 상속 등의 특징을 구현합니다.
  • 자바스크립트는 프로토타입(Prototype)이라는 개념을 통해 객체 지향 언어들의 특징을 구현합니다.
    따라서 자바스크립트를 명확히 정의하자면 클래스 기반이 아닌 '프로토타입 기반의' 객체 지향 언어인 것입니다.
    이 때문에 자바스크립트는 곧 프로토타입이라고 볼 수 있을만큼 프로토타입의 개념은 매우 중요합니다.
    하지만 프로토타입은 절대 쉬운 개념이 아니며, 깊게 들어갈수록 매우 어렵습니다.
    따라서 이번 토픽에서는 프로토타입에 대해 간딘히 개념만 공부하도록 하겠습니다.

     
  • 프로토타입(Prototype)?
    번역하면 '원형'이라는 뜻을 가지고 있습니다.
    클래스 기반에서는 '상속'이라는 개념을 통해 부모 클래스의 특징 등을 받아옵니다.
    자바스크립트에서는 클래스가 없기 때문에 어떠한 객체의 원형을 갖고 있는 부모 격의 객체를 지정하여 '상속'을 구현합니다.

 

 

 

프로토타입 객체

  • 프로토타입 객체(Prototype Object)에 대해 알아보도록 하겠습니다.

    객체를 생성할 때 리터럴 방법과 생성자 함수를 이용한 방법이 있습니다.
    사실 리터럴 방법도 내부적으로는 Object() 생성자 함수를 이용하여 생성합니다.
    즉, 모든 객체는 생성자 함수를 이용하여 만들어집니다.
    이 때, 생성자 함수를 생성할 때 내부적으로는 'prototype'이라는 프로퍼티를 생성합니다.
객체.prototype

 

  • 이것이 프로토타입 객체이며, 이는 자바스크립트의 기본 객체인 Object 특성을 갖고 있습니다.
    프로토타입 객체 안에는 원형이 되는 생성자를 갖고 있습니다.
    프로토타입 객체의 생성자는 처음 생성될 때에는 생성자 함수를 가리키고 있습니다.

     
  • 간단한 예제를 보도록 하겠습니다.

 

  • 상속 관계가 A객체가 가장 상위, B객체는 A객체를 상속받고, C객체는 B객체를 상속받는 상황입니다.
  • 이것을 간단하게 자바스크립트로 구현해보도록 하겠습니다.
function A() {}
A.prototype.car = "람보르기니";

function B() {}
B.prototype = new A();

function C() {}
C.prototype = Object.create(new B());

var obj = new C();

document.write(obj.car);

 

  • 자바스크립트는 생성자 함수를 통해 객체를 만드므로 A, B, C 객체 전부 빈 객체를 만들기 위한 생성자를 선언하였습니다.
function A() {}
function B() {}
function C() {}

 

  • 상속받을 객체를 지정하기 위하여 'prototype'이라는 프로퍼티를 사용합니다.
  • 이 때 상속받을 객체를 지정해야 하기 때문에 'new' 키워드를 이용하여 생성자 함수로 객체를 생성하거나, 객체를 생성하는 다른 방법인 Object.create() 함수를 이용할 수도 있습니다.
    단, Object.create() 함수를 사용할 경우 객체를 인자로 넣어주어야 하는데 여기에서는 B 객체를 생성하지 않았으므로 'new B()'로 객체를 생성하였습니다.
B.prototype = new A();
C.prototype = Object.create(new B());

 

  • 'obj'라는 객체는 C 객체 생성자 함수를 이용하여 생성합니다.
var obj = new C();

 

  • 마지막으로 최상위 객체인 A의 프로토타입 객체에 'car'라는 속성을 추가하고, '람보르기니' 값을 입력합니다.
A.prototype.car = "람보르기니";

 

  • 실행 결과

 

 

 

프로토타입 체인

  • 프로토타입 체인(Prototype Chain)에 대해 알아보도록 하겠습니다.
     
  • 위의 결과를 보면 프로토타입 객체에 생성자 함수를 통해 만든 객체를 설정해줌으로써 상속을 구현하였고, 이를 통해 A 객체의 프로토타입 객체에 'car' 속성에 접근하여 값을 가져온 것을 볼 수 있습니다.
     
  • 프로토타입 체인이란 이미 위에서 사용한 방식으로 알 수 있듯이 프로토타입 객체를 통한 객체 간의 연결을 통해 속성을 공유하는 것입니다.
    프로토타입 체인은 한 단계씩 상위 단계 프로토타입 객체에 해당 속성이 존재하는지의 여부를 판별하고 있으면 그 값을 사용하고 없으면 다시 한 단계씩 올라가는 방식입니다.
    따라서 위의 예제에서 C 객체의 프로토타입 객체에 'car' 속성이 없기 때문에, 상위 프로토타입 객체인 B 객체의 프로토타입 객체에 'car' 속성을 찾습니다. 또 없기 때문에 그 상위 단계인 A 객체의 프로토타입 객체에서 'car' 속성을 찾고 있기 때문에 그 값을 가져온 것입니다.

 

function A() { }
A.prototype.car = "람보르기니";

function B() { }
B.prototype = new A();
B.prototype.car = "BMW";

function C() { }

C.prototype = Object.create(new B());

var obj = new C();

document.write(obj.car + "<br>");

 

  • 중간에 객체 B의 프로토타입 객체에 'car' 속성으로 "BMW"가 먼저 검색되므로 "BMW"가 출력됩니다.

 

function A() { }
A.prototype.car = "람보르기니";

function B() { 
    this.car = "아우디";
}
B.prototype = new A();
B.prototype.car = "BMW";

function C() { }

C.prototype = Object.create(new B());

var obj = new C();

document.write(obj.car + "<br>");

 

  • 위의 예제에서는 같은 B 객체에서 'car' 속성이 있는 경우입니다.
    현재 생성자 함수를 통해 프로토타입 객체에 상속을 할당하였는데, 이 경우에는 생성자 함수의 속성이 우선 순위가 더 높습니다.
    따라서 "아우디"가 출력된 것을 볼 수 있습니다.

 

 

 

__proto__(비표준)

  • 프로토타입 객체를 통한 상속을 구현해보았습니다.
    모든 객체는 '__proto__'라는 속성을 가지고 있습니다.
    이는 상속을 구현할 때 프로토타입 객체를 가리키기 위한 링크입니다.
     
  • 하지만 이는 비표준 방식이므로 개발할 경우에는 사용하지 않는 것이 좋으며, 속성을 확인할 때에는 다음과 같이 사용하면 됩니다.
Object.getPrototypeOf()

 

 

function A() {
    this.car = "폭스바겐";
}
A.prototype.car = "람보르기니";

function B() {
    this.car = "아우디";
}
B.prototype = new A();
B.prototype.car = "BMW";

function C() { }

C.prototype = Object.create(new B());

var obj = new C();

document.write(obj.__proto__.constructor + "<br>");
document.write(Object.getPrototypeOf(obj).constructor + "<br>");

 

  • 'obj' 객체에서 '__proto__' 속성이 가리키고 있는 생성자 함수를 출력해본 예제입니다.
    최종 상속을 받고 있는 A 생성자 함수를 출력하고 있는 모습입니다.

 

 

 

댓글

댓글 본문
버전 관리
KNUT X LIKE LION
현재 버전
선택 버전
graphittie 자세히 보기