본문 바로가기
웹 프로그래밍

[JavaScript] - 자바스크립트와 객체지향 프로그래밍

by CHML 2016. 9. 4.
1. 자바스크립트와 객체지향 프로그래밍

자바스크립트(JavaScript)는 이름에서도 알 수 있듯이 스크립트 프로그래밍 언어이다. 그러나 정확히 말해서 자바스크립트는 객체 기반의 스크립트 프로그래밍 언어라고 할 수 있다. 자바스크립트를 이용하여 웹 어플리케이션을 개발하고자 프로그래밍할 때 많이 사용하는 DOM 객체, XMLHttpRequest 객체 등 자바스크립트에는 많은 객체가 존재한다.


[그림 1] 자바스크립트


대부분의 자바스크립트 코드는 브라우저 환경에서 실행된다. 불과 몇 년 전에는 브라우저에 탑재된 자바스크립트 엔진의 성능이 지금보다 매우 떨어졌었기 때문에 자바스크립트 코드가 많은 웹 페이지는 잘못 만들어진 페이지라고 말할 수 있었다. 그러나 지금은 웹 OS라는 말이 나올 정도로 브라우저가 어플리케이션을 구동하기 위한 새로운 환경으로 광범위하게 이용되고 있다. 자바스크립트 엔진의 성능이 향상되고 다양한 이전에 비해 수많은 기능을 제공하는 웹 어플리케이션이 개발됨에 따라 자바스크립트를 이용하여 객체지향 프로그래밍을 해야 하는 경우가 빈번하게 발생할 수도 있다.


2. 객체 정의

자바스크립트에서 객체를 정의하는 방법은 매우 많은 방법이 존재한다. 이 글에서는 비교적 이전 버전의 브라우저에서도 지원하는 function 키워드를 이용한 객체 정의 방법을 설명한다. 주의할 점은 function 키워드를 이용하였다고 function이 아니라는 것이다. 자바스크립트에서는 함수도 객체이고, 배열도 객체이고 모든 것이 객체이다.

아래의 [코드 1]은 자바스크립트의 function 키워드를 이용하여 Person이라는 객체를 정의한 것이다. [코드 1]에 정의된 Person 객체는 멤버 변수로 fullName, gender, age라는 변수를 갖고 있다.


1
2
3
4
5
function Person(fullName, gender, age) {
    this.fullName = fullName;
    this.gender = gender;
    this.age = age;
}
cs

[코드 1] Person 객체 정의 I


C++, Java의 클래스 정의와 약간 다른 점은 따로 생성자를 정의하지 않고 함수에 인자를 전달하는 방식으로 객체를 선언하면 객체의 선언 자체가 생성자의 역할을 한다는 것이다. 아래의 [코드 2]는 위에서 정의한 Person 객체를 선언하고, 멤버 변수에 접근하는 코드이다.


1
2
3
4
5
6
var person1 = new Person('name1''man'25);
 
console.log(person1.fullName);
console.log(person1.gender);
console.log(person1.age);
}
cs

[코드 2] Person 객체 접근


3. 멤버 함수

자바스크립트에서 객체의 멤버 함수를 정의하는 방법은 매우 다양하다. 이 글에서는 객체의 prototype 속성을 이용하여 멤버 함수를 정의하는 방법을 설명한다. 아래의 [코드 3]은 Person 객체에 멤버 변수의 값을 모두 출력하는 showInfo()라는 멤버 함수를 정의한 것이다.


1
2
3
4
5
6
7
8
9
10
function Person(fullName, gender, age) {
    this.fullName = fullName;
    this.gender = gender;
    this.age = age;
 }
Person.prototype.showInfo = function () {
    console.log(this.fullName);
    console.log(this.gender);
    console.log(this.age);
 }
cs

[코드 3] Person 객체 정의 II


Person 객체의 멤버 함수 showInfo()는 아래의 [코드 4]와 같이 호출할 수 있다. [코드 4]를 실행하면, 브라우저의 콘솔창에 name1, man, 25가 출력되는 것을 확인할 수 있다.


1
2
3
var person1 = new Person('name1''man'25);
 
person1.showInfo();
cs

[코드 4] Person 객체의 멤버 함수 showInfo() 호출


멤버 함수를 정의할 때 주의할 점은 객체 자신의 멤버 변수를 접근할 때는 항상 this.멤버변수의 형태로 접근해야 한다는 것이다.


4. 접근 범위 설정

앞의 [코드 3]과 같이 멤버 변수를 this 포인터를 통해 선언하면 객체 외부에서도 멤버 변수에 접근이 가능하다. 그러나 때로는 객체에 대한 접근을 제한해야할 필요가 있는데, 전통적인 객체지향 프로그래밍 언어인 C++, Java에서는 private 키워드를 제공하여 객체에 대한 접근을 제한할 수 있다. 자바스크립트에서도 [코드 3]을 약간만 수정하면 private 키워드와 같은 기능을 구현할 수 있다.


1
2
3
4
5
6
7
8
9
10
11
function Person(fullName, gender, age) {
    var fullName = fullName;
    var gender = gender;
    var age = age;
 
    this.showInfo = function () {
        console.log(fullName);
        console.log(gender);
        console.log(age);
    }
}
cs

[코드 5] 접근 범위를 제한하는 객체 선언


[코드 5]는 Person 객체를 선언하는 코드에서 멤버 변수를 this가 아닌, var 키워드를 이용하여 정의하고 있다. 자바스크립트에서는 var 키워드를 이용하여 멤버 변수를 선언할 경우, 객체 외부에서는 참조가 불가능하게 된다. 또한, var 키워드로 정의된 멤버 변수는 prototype로 정의된 함수에서도 접근이 불가능하기 때문에 멤버 함수 showInfo()를 객체 내부에, 그리고 showInfo()를 객체 외부에서 참조가 가능하도록 this 포인터를 이용하여 정의하였다. Person 객체를 [코드 5]와 같이 선언하면, Person 객체의 멤버 변수는 오직 멤버 함수 showInfo()를 통해서만 출력할 수 있다.


5. 객체 상속

객체 기반의 코드를 구현할 때, 가장 핵심이 되는 두 가지 기능을 꼽자면 아마도 접근 범위의 제한과 상속일 것이다. 자바스크립트에서는 객체에 대한 접근 범위의 제한뿐만 아니라, 객체간의 상속 기능도 제공한다. 아래의 [코드 6]은 Person 객체를 상속받는 Student 객체에 대한 정의 및 Student 객체의 멤버 함수를 실행하는 코드이다..


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
function Person(fullName, gender, age) {
    this.fullName = fullName;
    this.gender = gender;
    this.age = age;
}
Person.prototype.showInfo = function () {
    console.log(this.fullName);
    console.log(this.gender);
    console.log(this.age);
}
Person.prototype.speak = function () {
    console.log('Hello, my name is ' + this.fullName + '.');
}
 
function Student(fullName, gender, age) {
    this.comHomework = false;
 
    Person.call(this, fullName, gender, age);
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.showInfo = function () {
    console.log(this.comHomework);
    console.log(this.fullName);
    console.log(this.gender);
    console.log(this.age);
}
Student.prototype.study = function () {
    console.log('I am studying...');
    this.comHomework = true;
}
 
window.onload = function () {
    var student1 = new Student('name1''man'25);
 
    student1.study();
    student1.showInfo();
}
cs

[코드 6] Student 객체 정의 및 멤버 함수 실행


[코드 6]에서 1~13번째 줄에서는 Person 객체를, 15~31번째 줄에서는 Student 객체를 정의하고 있다. 그 다음, 33~38번째 줄에서는 Student 객체에 대한 인스턴스 (instance)를 생성하여 Student 객체의 멤버 함수인 study()와 showInfo()를 호출하고 있다. 객체의 상속을 위해 추가한 코드와 추가된 코드의 기능은 아래와 같다.


  • [18번째 줄] Person.call(this, fullName, gender, age): 상속받는 Person 객체의 생성자를 호출한다.
  • [20번째 줄] Student.prototype = Object.create(Person.prototype): Student 객체의 prototype를 Person 객체의 prototype로 정의한다.
  • [21번째 줄] Student.prototype.constructor = Student: 현재 Person의 생성자를 참조하고 있는 Student 객체의 생성자를 다시 Student 객체의 생성자로 변경한다.

자바스크립트에서는 언어 차원에서 protected와 같은 키워드를 제공하지 않기 때문에 여러 기법을 조합하여 protected 기능을 구현해야 한다. 따라서, [코드 6]에서는 코드를 간단하게 하기 위해 protected 기능을 따로 구현하지 않고, public과 같은 this 포인터를 이용하여 Student에 상속되는 Person의 멤버 변수를 선언하였다.