본문으로 바로가기

자바스크립트 객체지향 프로그래밍

자바스크립트를 객체지향 프로그래밍이라고 부를 수 있는 것과 관계된 것 중에 생성자, 프로토타입 인스턴스, 프로퍼티와 메서드, 클래스 프로퍼티와 메서드, 비공개 멤버에 대해 간단히 알아보는 시간을 가져보겠습니다.





자바스크립트 생성자란?

여러 객체지향 프로그래밍 언어에서는 객체의 클래스를 정의한 다음 해당 클래스의 인스턴스에 해당하는 개별 객체를 생성하는 것이 가능합니다. 

자바스크립트에서는 진정한 클래스를 지원하지는 않지만 자바스크립트 객체를 생성하는 생성자 함수를 제공하고 있습니다.


자바스크립트 생성자는 자바스크립트 객체를 생성하는 데 사용되는 함수를 말합니다. 

자바스크립트 생성자는 new 연산자와 함께 사용되는데, 먼저 프로퍼티가 없는 새 객체를 생성한 후 생성자 함수를 호출하고 새 객체를 this 키워드의 값으로 전달하며, 객체가 사용되기 전에 설정돼 있어야 할 프로퍼티를 설정하는 역할을 합니다.


생성자 함수는 직접 정의할 수 있는데, 단지 this에 프로퍼티를 추가하는 함수를 작성하기만 하면 됩니다. 

다음 예제를 살펴봅니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
    // 보통 생성자 함수는 반환값이 없다.
}
 
point1 = new Point(5,5);
point2 = new Point(8,8);
 
console.log(JSON.stringify(point1));
console.log(JSON.stringify(point2));




자바스크립트 프로토타입(prototype)

모든 자바스크립트 객체는 그것의 프로토타입 객체에 대한 내부 참조를 가지고 있으며, 프로토타입 객체로부터 프로퍼티를 상속받습니다. 

모든 함수는 함수가 정의됐을 때 자동으로 생성되고 초기화되는 prototype 프로퍼티를 가지고 있습니다. 

이러한 프로토타입 객체에 추가하는 프로퍼티는 생성자로 초기화된 객체 프로퍼티로 나타나게 됩니다.


자바스크립트 프로토타입 예제는 다음과 같습니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
}
 
Point.prototype.add = function(){
    return this.x + this.y;
}   
 
point1 = new Point(5,5);
point2 = new Point(8,8);
 
console.log(point1.add());  // 10
console.log(point2.add());  // 16


메서드와 프로퍼티는 객체가 생성된 이후에도 동적으로 프로토타입에 추가될 수 있습니다. 

다음 예제를 살펴보도록 합니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
}
 
// 객체를 먼저 생성
point1 = new Point(5,5);
point2 = new Point(8,8);
 
// 프로토타입에 메서드를 추가
Point.prototype.add = function(){
    return this.x + this.y;
}   
 
console.log(point1.add());  // 10
console.log(point2.add());  // 16


자바스크립트 프로토타입을 쓰는 이유

자바스크립트 프로토타입의 이점은 다음과 같습니다.

  • 객체지향적이고 상속을 사용할 수 있습니다.
  • 프로토타입 객체를 사용하면 객체가 프로토타입의 프로퍼티를 상당수 상속할 수 있어서 각 객체에 필요한 메모리의 양을 대폭 줄일 수 있습니다.





인스턴스 프로퍼티와 메서드

자바스크립트는 객체지향 언어이고, 같은 클래스(생성자 함수)의 객체가 여러 개 있을 수 있으며, 각 객체는 해당 클래스의 인스턴스에 해당됩니다.


인스턴스 프로퍼티

모든 객체는 인스턴스 프로퍼티의 사본을 자체적으로 가지고 있습니다. 

다음 예제를 살펴보도록 합니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
}
 
point1 = new Point(5,5);
point2 = new Point(8,8);
 
console.log(point1.x);  // 5
console.log(point2.y);  // 8

인스턴스 프로퍼티에는 개별 객체(이를테면 point1.x)를 통해 접근할 수 있습니다.


인스턴스 메서드

인스턴스 메서드는 특정 인스턴스나 객체를 대상으로 호출됩니다. 

인스턴스 메서드를 구현할 때는 this 키워드를 이용해 메서드를 호출할 인스턴스나 객체를 참조할 수 있습니다. 

다음 예제를 살려봅니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
}
 
// 객체를 먼저 생성
point1 = new Point(5,5);
point2 = new Point(8,8);
 
// 프로토타입에 메서드를 추가
Point.prototype.add = function(){
    return this.x + this.y;
}   
 
console.log(point1.add());  // 10
console.log(point2.add());  // 16

인스턴스 메서드는 클래스의 모든 인스턴스가 공유합니다.




클래스 프로퍼티와 메서드

위에서는 인스턴스 프로퍼티와 메서드에 알아보았다면 여기서는 클래스 프로퍼티와 메서드에 대해 간략히 알아봅니다.

클래스 프로퍼티

자바스크립트에서 클래스 프로퍼티는 클래스의 각 인스턴스와 연관된 것이 아닌 클래스 자체와 연관된 프로퍼티를 말합니다. 

클래스의 인스턴스가 얼마나 생성됐느냐와 관계없이 각 클래스 프로퍼티는 각각 하나씩만 존재합니다. 

자바스크립트에서 클래스 프로퍼티를 정의하려면 생성자 함수 자체의 프로퍼티로 정의하기만 하면 됩니다. 

이는 자바스크립트 함수 역시 객체이기 때문입니다. 


다음 예제를 살려봅니다.

javascript
function Circle(r){
    this.radius = r;
}
 
// 클래스 프로퍼티를 정의
Circle.PI = 3.14159265;
 
Circle.prototype.area = function(){
    return Circle.PI * this.radius * this.radius;
}   
 
c1 = new Circle(10);
 
console.log(c1.area()); // 314.159265


클래스 메서드

클래스 메서드는 클래스의 인스턴스가 아닌 클래스와 연관된 메서드입니다. 

자바스크립트에서 클래스 메서드를 정의하려면 적절한 함수를 생성자의 프로퍼티로 만들기만 하면 됩니다. 

클래스 메서드는 생성자 함수를 통해 호출되기 때문에 this 키워드는 클래스의 특정 인스턴스를 참조하지 않습니다. 

그래서 보통 클래스 메서드에서는 this를 전혀 사용하지 않습니다. 


 클래스 메서드의 예는 다음과 같습니다.

javascript
function Point(x,y){
    this.x = x;
    this.y = y;
}
 
// 클래스 메서드를 정의
Point.getHigherPoint = function(a,b){
    if (a.x > b.x) return a;
    else return b;
}   
 
point1 = new Point(5,5);
point2 = new Point(8,8);
 
console.log(Point.getHigherPoint(point1, point2).y);    // 8




비공개 멤버와 메서드

자바스크립트에서 비공개 멤버는 생성자로 만드는데, var 키워드를 이용해 정의한 변수와 생성자의 매개변수는 비공개 멤버가 됩니다. 

비공개 멤버는 생성자 함수 밖에서 접근할 수 없으며, 오직 생성자 함수 안에서만 접근할 수 있습니다. 

이를 데이터 캡슐화(data encapsulation)라고 합니다. 


예제는 다음과 같습니다.

javascript
function Circle(r){
    // 비공개 프로퍼티
    var radius = r;
 
    // 비공개 메서드
    var getArea = function(){
        return Circle.PI * radius * radius;
    }
 
    // 공개 메서드
    this.area = function(){return getArea()}
}
 
// 클래스 프로퍼티를 정의
Circle.PI = 3.14159265;
 
c1 = new Circle(10);
 
console.log(c1.area()); // 314.159265



Jaehee's WebClub



[출처] 코딩누리