오늘은 자바스크립트를 배운 이래로 가장 어지러운 날이다.
오늘의 주제는 객체지향 프로그래밍이다. 객체지향이란 무엇일까? 일단 생전 처음 듣는 말이다. OOP(Object-oriented prograiming) 을 한글로 직역하다 보니, 우린 익숙치 않을 수밖에 없다. 그렇다면 객체지향은 왜 존재 하는 것일까? 이것은 정확한 무엇인가가 아니라 프로그래밍 방식 또는 방법론이다. 그래서 더욱 이해하기가 모호하고 애매할 것이다. 이것은 오직 자바스크립트를 위한 것만이 아닌 프로그래밍을 하는 모두에게 갖춰져야할 기본 같은 것이다.
나는 이 객체지향을 하나의 회사를 예로 들어보겠다. 상사가 부하직원들에게 일을 할당 한다고 가정해 보자.
이렇게 상사가 일일이 한사람씩 모두에게 오늘의 과업을 알려준다고 하자.
이 상황을 코드로 표현해 보자면 이렇다.
let boss = ' 업무를 합니다.'
let employee1 = '디자인' + boss;
let employee2 = '프로그래밍' + boss;
let employee3 = '마캐팅' + boss;
console.log(employee1) // 디자인 업무를 합니다.
console.log(employee2) // 프로그래밍 업무를 합니다.
console.log(employee3) // 마케팅 업무를 합니다.
자 여기서 문제점은 뭘까? 아직 감이 안올것이다. 그렇다 이처럼 직원이 소수인 경우는 한명한명씩 일을 지시하는 것은 크게 힘들지 않을 것이다. 그러나 직원이 수십명 수백명이 되는 경우는?
let boss = ' 업무를 합니다.'
let employee1 = '디자인' + boss;
let employee2 = '프로그래밍' + boss;
let employee3 = 'something1' + boss;
let employee4 = 'something2' + boss;
let employee5 = 'something' + boss;
let employee6 = 'something4' + boss;
let employee7 = 'something5' + boss;
let employee8 = 'something6' + boss;
let employee9 = 'something7' + boss;
let employee10 = 'something8' + boss;
.
.
.
let employeeN = 'somethingN' + boss;
벌써부터 복잡해진다. 특히 일을 지시하는 상사는 일을 지시하는데 시간을 다 보낼 것이다. 코드 역시 굉장히 비효율적이다.
자 그럼 조금 더 효율적으로 해보자. 일을 시작하라고 게시판에 게시를 해보자.
직원들은 게시판을 각자 게시판을 참고하고 일을 시작하면 된다. 이를 코드로 표현해 보자.
let bulletinBoard = function() {
return this.task + ' 업무를 합니다.'
}
let employee1 = {
task: '디자인',
seeThe: bulletinBoard,
};
let employee2 = {
task: '프로그래밍',
seeThe: bulletinBoard,
};
let employee3 = {
task: '마케팅',
seeThe: bulletinBoard,
};
console.log(employee1.seeThe()) // 디자인 업무를 합니다.
console.log(employee2.seeThe()) // 프로그래밍 업무를 합니다.
console.log(employee3.seeThe()) // 마케팅 업무를 합니다.
이렇게 직원들은 게시판을 참조 하는 것만으로도 일을 시작할 수 있다. 그리고 게시판을 보지 않는 다면 일을 하지 않을 수도 있듯이 객체 안에 담겨져 있는 코드를 필요 할 때만 꺼내 쓸 수 있다. 객체지향은 사람의 행동을 최대한 모방한 것이라고도 볼 수있다. 지금은 설명을 위해 단순하게 표현 하였지만, 객체지향 프로그래밍을 하면 더욱 유연하고 또 코드의 재활용성이 높아지며, 중복되는 코드를 줄일 수 있다. 가장 큰 장점은 바로 불필요한 연산을 줄이면서 메모리의 부담을 들고 더욱 빠른 결과를 볼 수있다.
그럼 자바스크립트에서 객체지향 프로그램을 하기 위해 가장 필요한 것은 무엇일까?
바로 객체(Object)이다. 우리가 정보를 담아서 꺼내 쓸 수 있는 박스를 만들어야 하는데 그 박스, 곧 객체를 만들어야 객체지향 프로그램이 가능하다. 자바스크립트에서 객체를 만드는 방법이 몇가지 있다.
첫 번째, 객체 리터럴을 이용하는 방법
let employee = {};
그냥 단순히 객체 리터럴을 이용하여 선언하는 것이다. 선언 후 속성과 값을 추가할 수 있으며, 값을 참조도 가능하다.
let employee = {name: 'sangrae', age: '29'};
employee['occupation'] = null
console.log(employee) // {name: 'sangrae', age: '29'}
console.log(employee.name); // sangrae -> dot notation
console.log(employee['age']); // 29 -> braket notation
두 번째, Object() 생성자를 이용하는 방법
let employee = new Object()
console.log(employee) // {}
employee.age = 28
employee['name'] = 'sangrae'
console.log(employee) // { age: 28, name: 'sangrae' }
세 번째, 생성자 함수를 직접 만들어 이용하는 방법
let BulletinBoard = function(tasks) {
this.task = tasks
this.seeThe = function () {
return this.task + ' 업무를 합니다.';
}
}
let employee1 = new BulletinBoard('디자인');
let employee2 = new BulletinBoard('프로그래밍');
let employee3 = new BulletinBoard('마케팅');
console.log(employee1) // BulletinBoard { task: '디자인', seeThe: [λ] }
console.log(employee2.seeThe()) // 프로그래밍 업무를 합니다.
console.log(employee3.seeThe()) // 마케팅 업무를 합니다.
생성자 함수를 이용하는 방법을 굳이 두가지로 나눈 이유는 바로 이 생성자 함수와 new를 이용했을 때의 효율에 대해 설명하기 위해서이다. 앞서 설명한 객체지향에서 이용한 비유를 또 들어보겠다. 그러나 다른 점은 위에서 본 코드를 이용할 때 새로운 task, 즉 새로운 값을 받을 때 똑같은 형태의 객체를 하나 더 만들어 줘야 했을 것이다. 이는 중복이 발생하고 비효율 적인 일이다. 그래서 생성자 함수를 만들어 주고 new라는 키워드를 이용해 객체로 할당하는 것이다. 이는 코드의 재사용성을 높이고 중복을 방지하는 객체지향의 특성을 보여준다. (주의, 생성자 함수를 만들 때 일반 함수와 구분하기 위해 첫 글자를 대문자로 쓴다.)
위 특징을 이용해 우린 더 나아가 생각해 볼 수 있다. '직원이라면 당연히 일을 해야하는 것을 알고 있어야 하지 않은가?' '굳이 업무 시작을 게시판을 봐야 할 수 있는 것인가?'. 그렇다 조금 불쌍하지만 우린 직원들에게 일을 해야하는 의무를 머릿속에 심어주자!
프로토타입이란 무엇일까? 직역하자면 원형이다. 자바스크립트에선 이 프로토타입을 이용해 생성자 함수 원형에 속성을 부여할 수 있다는 것이다. 함수도 역시 객체이므로 프로퍼티를 가질 수 있는데 프로토타입이라는 특수한 프로퍼티를 이용한다는 것이다.
let Employees = function(tasks) {
this.task = tasks
}
Employees.prototype.work = function () { // Emplyees 함수이므로 객체가 된다 브라켓 노테이션을 써도 결과는 똑같다.
return this.task + ' 업무를 합니다.'
}
let employee1 = new Employees('디자인');
console.log(employee1) // Employees { task: '디자인' }
console.log(employee1.work()) // 디자인 업무를 합니다.
여기서 알 수 있는점은 employee1은 속성 task만을 가진 객체인데. work()라는 함수가 사용 가능하게 되었다. 이는 프로토타입을 이용하여 Employees 라는 생성자 함수의 원형에 속성을 추가해 주었고, 비록 employee1의 객체에는 없는 속성 이지만 거기에 부여된 속성 자체에는 존재하는 것이다. 그래서 우린 필요할 때만 꺼내어 쓰기가 가능해졌다. 비유해서 말하자면 직원이라는 신분을 가지면 일을 해야하는 것은 당연한 것이기에 굳이 명시하지 않아도 머릿속에는 그렇게 행동해야한다는 패턴이 내장되어 있는 것이다. 이 또한 객체지향 프로그래밍의 특성을 보여주는 것이다.
프로토타입으로 우린 더욱 유연한 프로그래밍을 할 수있다. 어떻게 할 수 있을까? 또 한번 비유를 들어보자. 우린 회사를 꾸준히 다니면 승진이 가능할 것이다. 이는 상속을 이용하여 표현할 수있다. 이는 다음에 포스팅 하겠다.