테스트 사이트 - 개발 중인 베타 버전입니다

JavaScript로 Class 없이 OOP 하기

· 9년 전 · 895 · 17

시작하며

한국 루비 커뮤니티 2015년 대림절 달력 첫 글을 JavaScript로 옮겨보겠습니다. 그냥 Copy&Paste해서 몇몇 부분만 고칠 거라 이상해도 양해 부탁드립니다.

OOP라고 하면 Class와 Instance 개념을 떠올리는 경우가 많습니다. 객체끼리 서로 협력한다는 기본 원리만 가지고도 프로그래밍이 가능하다면 어떻게 될까요? Class가 없는 언어 중 하나인 JavaScript(ES6 이전 기준)를 통해 Class 없는 OOP를 경험해 봅시다.

 

준비물

  • Node.js
  • 흥미
  • 용기
  • 사랑과 우정 (필수는 아님)

 

객체 만들기

간단한 객체를 만들어 봅시다. 일단 Node 인터프리터 환경을 실행하죠.

 

$ node

 

객체가 뭘까요? 객체를 설명하는 방법은 너무나도 많은데, 추상화 단계를 너무 높이지 않고 손에 만져지는 걸로 살펴봅시다. “한 소년이 있었습니다” 정도면 어떨까요?

 

var boy = new Object();

소년이 하나 만들어졌습니다. 제대로 잘 됐는지 한번 확인해 보죠.

 

console.log(boy);

결과:

{}

우리가 잘 아는 게 나왔죠? 그냥 빈 객체를 만들 땐 힘들게 `new Object` 하지 말고, 그냥 `{}` 쓰시면 됩니다.

 

객체에 특성 부여하기

소년을 소년이라고 부르니 뭔가 밋밋한 것 같네요. 소년에게 이름을 붙여주면 어떨까요? 무난하게 “강동원”이라고 합시다. 객체에 이름을 넣어주면 간단히 해결됩니다.

 

boy.name = 'Kang Dong-won';

자, 이제 소년의 이름을 한번 확인해 볼까요?

 

console.log(boy.name);

결과:

Kang Dong-won

또 다른 객체 만들기

소년은 혼자 있으니 슬펐습니다. 그러니 여자친구를 하나 만들어보죠.

 

var girl = Object.create(boy);

강동원을 프로토타입으로 소녀 객체가 만들어졌습니다. 강동원을 프로토타입으로 삼고 있기 때문에 한가지 문제가 있습니다. 소녀가 강동원가 똑같이 행동한다는 거죠.

 

console.log(girl.name);

결과:

Kang Dong-won

“그럴 땐 얘기를 나누자 거울 속의 나하고”가 아니라면 이 상황을 벗어나야겠죠? 여자친구에게 이름을 하나 지어줍시다.

 

girl.name = 'Don Don';

이제 둘을 사랑스럽게 엮어줄 수 있겠네요.

 

console.log([boy.name, girl.name].join(''));

결과:

Kang Dong-won ♥ Don Don

액션!

Class 없이 객체를 만들고, 특성을 부여하고, 이걸 활용하는 게 얼마나 쉬운지 우리는 경험했습니다. 강동원에게 구마 의식을 수행하게 하는 것도 이제는 쉽겠죠?

 

girl.bad = true;

// 소녀의 상태 확인
console.log(girl.bad);

// 강동원에게 구마 능력 부여
// ES6 arrow function 사용함. MDN 문서 참고: http://bit.ly/1NQfCfS
boy.performExorcism = target => { target.bad = false };

// 구마
boy.performExorcism(girl);

// 소녀의 상태 다시 확인
console.log(girl.bad);

 

정리하며

객체지향의 핵심은 객체입니다. 타입을 명확히 하고 싶어서 클래스를 사용하는 거죠. 이 둘을 명확히 구분해서 쓸 때, 유연함과 견고함의 균형을 맞출 수 있지 않을까요?

 

P.S. TypeScript도 한번 써보세요!

 

댓글 작성

댓글을 작성하시려면 로그인이 필요합니다.

로그인하기

댓글 17개

되게 로맨틱한 코드가 나오는군요. ㅎㅎ
맛깔스럽게 잘 쓰시네요...ㅎㅎ

꼬으는건 아니구요.
모바일 과 PC 브라우져을 같이 사용한다고 봤를때

IE8 은 ES3 까지만 지원하는것으로 알고 있고, ( IE5 는 조금 지원 )
ES5 도 IE9 이상에서 제대로 지원하는걸로 알고 있는 상황이라
ES6 을 사용하기에는 시기 상조 아닐까요?

script 을 객체까지 지원하는것도 M$ 에서는 엣지부터 지원한다고 메뉴얼에
나와 있더라구요...계속 걸리는 IE 라...

제가 잘못 알고 있다면 지적 부탁 드립니다.
대부분은 이렇게 잘 쓰고 있습니다: http://bit.ly/1ZWsXuO

JavaScript는 처음부터 객체지향 프로그래밍 언어였기 때문에 객체를 지원하지 않는 경우는 없습니다. 객체지향에 클래스가 반드시 필요한 건 아니란 걸 이야기하는 글이지요(OOP는 크게 Class-based와 Prototype-based로 나뉩니다).
제가쓴 위의 뎃글은 M$ 메뉴얼에 나와 있는것이라....
"IE 가 걸린다" 라는 말씀을 드린거였어요.

M$ 메뉴얼이 아닌, 일부 정리된 거지만...

http://kangax.github.io/compat-table/es5/
~
http://kangax.github.io/compat-table/es7/ <--- 엣지만 지원
http://kangax.github.io/compat-table/non-standard/
제 링크를 확인해 보세요 :)
예에...봤어요.
http://kangax.github.io/compat-table/es7/ <-- 에도 babeljs 나와요.

딴지 걸려던게 아니구요....IE 때문에....ㅋ
해당 사이트의 제목은 다음과 같습니다: “Babel · The compiler for writing next generation JavaScript”

Babel이 바로 코드 컨버터입니다. ES6,7 등으로 작성된 JS 코드를 이전 버전으로 변환해 주는 거죠. 예를 들어 온라인 실행기를 보시면(http://bit.ly/1ZhPEHs ), 왼쪽에 있는 코드가 오른쪽으로 바뀌게 되는 겁니다.

이렇게 해서, 다들 잘 쓰고 있죠.

Compatibility Table을 보시면 브라우저 외에 컨버터들이 포함되는데(Traceur, Babel, JSX, TypeScript), 심지어 브라우저보다 앞에 있죠. 왜냐면 요새는 다들 그렇게 쓰고 있기 때문입니다. 브라우저가 지원하냐가 중요하지 않고, 내가 쓰는 컨버터가 제대로 처리해주냐가 훨씬 중요한 겁니다.
바라보는 방향이 틀린건지....

저는 ES6,7 에 대해서 Babel 이 무슨 일을 하든, 뭘 하든
IE8 이상에서 되느냐? ...
IE8~11 에서 되느냐? ...

이게 핵심입니다.
바라보는 방향이 다른 게 아니라, Babel이 뭔지 이해하지 못 하고 계신 것 같습니다. 마지막으로 상세히 풀어서 말씀드리겠습니다.


1. 개발자는 ES6를 이용해 다음과 같이 코드를 작성합니다.

var say = (name) => { console.log('Hello, ' + name) };
say('Dong-won');


2. Babel을 이용해 이 코드를 다음과 같이 변환합니다.

'use strict';

var say = function say(name) {
console.log('Hello, ' + name);
};
say('Dong-won');


3. 이제 IE에서도 아무 문제가 일어나지 않습니다.


4. 혹시라도 코드를 바꿀 일이 있으면 1번으로 돌아갑니다.



P.S. 기존에 LESS나 SCSS 등을 써보신 적이 있다면 바로 이해하실 수 있습니다.
그러면, 바로 여쭤볼께요..

제일 마지막에 적으신 코드이외에 다른것들도 Babel 을 이용하면
ES5 ~ 7 방식을 사용해서 구현하는 경우
IE 8 이상에서 에러 없이 잘 돌아가나요?

제가 댓글에 적은
http://kangax.github.io/compat-table/es5/ 사이트 운영하시는분이 유명 하신분이시고
실수하셨를것 같지 않거든요.

게시글 목록

번호 제목
32341
32339
32326
32325
32322
32319
32318
32316
32315
32313
32312
32311
32310
32304
32303
32300
32293
32292
32291
32285
32284
32275
32271
32268
32265
32261
32258
32257
32255
32254
32253
32251
32250
32249
32247
32246
32245
32244
32243
32242
32241
32240
32239
32238
32237
32236
32232
32229
32228
32227
32217
32215
32214
32213
32211
32207
32196
32193
32192
32190
32188
32186
32184
32173
32172
32171
32167
32165
32163
32162
32158
32157
32155
32151
32149
32135
32132
32127
32125
32122
32120
32119
32117
32116
32115
32114
32112
32111
32109
32107
32104
32103
32102
32101
32094
32089
20404
31036
8279
8268