자바스크립트는 멀티 패러다임 언어로 명령형, 함수형, 프로토타입 기반 객체 지향 언어다. 비록 다른 객체지향 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력들을 지니고 있다, 간혹 클래스가 없어서 객체 지향이 아니라고 생각하는 사람들도 있으나 프로토타입 기반의 객체지향 언어이다.
다른 언어들과 다른 점이 있었으니..
C++, JAVA: Class 기반 언어
Javascript: Prototype 기반 언어
프로토타입이란?
- 프로토타입은 '원형'이라는 의미를 갖고 있습니다. Javascript에서 객체를 만드는 행위는 이 프로토타입을 기술을 응용해서 만들어지는 것인데요. ES6에서 도입된 class 기술도 사실은 다른 언어처럼 오리지널 class를 만든 것이 아니고, 프로토타입으로 class기술을 재현한 것이라고 보면 되겠습니다.
(* 자세한 내용은 검색하시거나, 코어자바스크립트라는 책을 읽으면 도움 될 것입니다."
// 1. 생성자 함수
function F() {}
var obj1 = new F();
obj1.name = 'Lee';
// 2. class
class Animal {
constructor(name,weight){
this.name = name;
this.weight = weight;
}
// 필요한 메서드를 정의
eat() {...}
}
const pig = new Animal('pig', 60);
// 3. Object() 생성자 함수
var obj2 = new Object();
obj2.name = 'Lee';
// 4. 객체 리터럴
var obj3 = {};
obj3.name = 'Lee';
이 모든 방식이 프로토타입의 상속과 관련되어 있습니다. 생성자 함수, class를 프로토타입(원형)이고, 프로토타입을 상속해서 만들어진 객체 obj3, pig를 인스턴스라고 부릅니다.
생성자 함수와 class는 틀... 예를 들어 붕어빵 틀 이고,
만들어진 인스턴스(객체)를 붕어빵에 비유하는게 좋겠습니다.
참고자료 - 제로초님 글
객체 지향은 객체안에서 상태(속성)를 나타내는 변수들과 객체의 행동(메서드)으로 이루어져 있고, 각각의 객체들은 협력하는 과정을 통해서 대규모 소프트웨어를 만듭니다. 객체지향은 객체들간의 협력, 메시지, 책임이 중요하다.
즉 객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체로 만들고, 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
객체 지향 프로그래밍은 크게 추상화, 캡슐화, 상속, 다형성의 네가지 특징을 가지고 있습니다.
// 음료 객체
class Beverage {
constructor(props) {
this.state = {
amount: 0.5,
};
}
drunk() {
this.state = { ...this.state, amount: 0 };
}
}
// -> 음료 객체에 많은 상태와 기능들이 있지만 필요한 기능들만 간소화한 생테
지인과의 대화를 예를 들어보자.
1. 지인: "야 오랜만이다. 나 이번에 야먀하의 어떤 모델 피아노와 삼익의 어떤 모델 피아노, 스타인웨이 피아노, 가와이 피아노, 영창 피아노... //생략
~중에 고급지고 연주하기에도 편하고 소리도 맑은 스타인웨이 피아노로 샀어!!
2. 나: 와 그래..?(듣느라 벌써 지침) 좋은 피아노 샀네~! 나도 한 번 연주해 볼 기회를 줘~
여러분이 피아노에 관심이 있었다면 모르겠지만, 관심이 전혀 없다면 친구의 얘기에 애매한 반응을 하거나 재밌는 얘기는 아니라고 생각 확률이 높을 수 있겠습니다. 혹시 이렇게 생각할 수도 있겠죠
"뭐.. 그냥 다 같은 피아노아니야?
타인과의 대화를 할 때 우리는 추상화를 많이 사용한다고 하네요. 인간의 뇌는 단순한 걸 좋아하거든요. 앞선 예시를 조금 바꿔보겠습니다.
- 지인: 나 이번에 스타인웨이 그랜드 피아노샀자나, 너무 좋아 ㅠㅠ
- 나: 정말? 그 피아노 가격도 비싸고 소리도 좋기로 정평이 나 있고, 외관도 삐까뻔쩍(?)하자나? 전문가용 피아노 아니야? 와 정말 부럽다~~😏
신기하게도 스타인웨이 그랜드 피아노 만으로도 어떤 특징들을 갖고 있는지 단번에 파악하기가 수월합니다.
여러분은 피아노🎹를 생각하면 어떤 모양을 생각하시나요? 대체로 그랜드 피아노, 업라이트 피아노를 떠올릴 것입니다. 이 또한 추상화입니다.
여기서 객체란 인간이 느끼고 인식할 수 있는 모든 것을 말함. (잠시만 여러분 주위를 둘러보세요. 여러분의 눈에 보이는 모든 것들 그리고 독자께서 인지할 수 있는 모든 것들이 객체입니다)
class Yamaha {
#name = 'YAMAHA'
#price = 20000$
color = 'black'
play() {...}
}
// object
let yamaha = new Yamaha();
yamaha.color = 'black' // public한 필드는 외부에서 수정이 가능한 잠재적 위험이 있어서 개인정보 같은 중요정보나 외부에서 접근하면 안되는 프로퍼티에는 캡슐화가 필수이다.
yamaha.name = 'YoungChang'; // Error TS18013: Property '#name' is not accessible outside class 'Human' because it has a private identifier.
javascript에서는 캡슐화를 위한 private 변수는 제공하지만 protected 변수는 제공하지 않습니다. 따라서 protected 변수 구현을 위해 변수명 앞에서 _표시를 해주어 protected 변수를 표시합니다.
자바스크립트에서 private와 protected 사용법
장점 | 단점 |
---|---|
재사용으로 인한 코드가 줄어든다 | 상위 클래스의 변경이 어려워진다 |
범용적인 사용이 가능하다 | 불필요한 클래스가 증가할 수 있다 |
자료와 메서드의 자유로운 사용 및 추가가 가능하다 | 상속이 잘못 사용될 수 있다 |
상속과 추상화를 통해서 객체의 일부분을 재사용을 하는 방법을 찾게 되었습니다.
반에 있는 친구들에게 '안녕?'이라고 인사하면 친구들 각각의 반응이 모두 다를 것이다.
객체의 다형성도 마찬가지다. 객체의 다형성이란 객체들마다 다르게 동작하는 것을 말한다.
javascript는 java와 달리 interface에 대한 기능을 제공하지 않는다.
class Animal {
constructor(sound) {
this.sound = sound;
}
move() {
console.log('동물이 움직여요');
}
}
class Cat extends Animal {
constructor(sound){
super(sound);
this.move();
}
move() {
console.log(`동물이 ${sound} 움직여요`);
}
}
let animal = new Animal();
let cat = new Cat(); // 동물이 움직여요
let cat2 = new Cat('재빠르게');
animal.move(); // 동물이 움직여요
cat2.move() // 동물이 재빠르게 움직여요
// 제로초님
var Animal = function() {
};
Animal.prototype.move = function() {
console.log('동물이 움직여요');
};
var Cat = function() {
Animal.apply(this, arguments); // 속성 상속받는 방법
}
Cat.prototype = Object.create(Animal.prototype); // 프로토타입 상속 방법
Cat.prototype.constructor = Cat; // 버그 패치
console.log(new Animal().move()); // 동물이 움직여요
console.log(new Cat().move()); // 동물이 움직여요
Cat.prototype.move = function(sound) { // 오버라이딩
console.log(sound + ' 움직여요');
return '야옹';
};
console.log(new Cat().move('살금살금')); // 살금살금 움직여요
제로초님의 예시를 가져왔다 (한 번 쭉 읽어보고 오버라이딩에 대해 이해해보자.)
근데 오버라이딩은 뭘까?
오버로딩은 하나의 함수를 유연하게 활용하고 싶을 때 사용
오버라이딩과 오버로딩
객체지향과 함수형 프로그래밍을 공부하면서 자바스크립트에서 둘을 조화롭게 사용할 수 있다면 프로그래밍 능력을 한 층 더 끌어올릴 수 있지 않을까 란 생각을 해보게 됐습니다.
자바스크립트는 멀티 패러다임 언어인만큼 객체지향과 함수형을 조화롭게 사용하는 것이 js를 잘 다루는 개발자라고 볼 수 있겠습니다.
데이터와 메소드를 통해 독립적인 작은 프로그램으로써 만들어 편리하게 재사용하는 장점을 취하되 객체들의 결합도가 높아져서 프로그램이 복잡해지지 않도록
객체로 만들지 않아도 되는 부분은 함수형으로 만들어서 코드의 덩치가 커져도 유지보수하기 좋게 재사용이 편리한 코드를 만들어 내는 것이 js를 잘하는 것이라고 할 수 있겠습니다.