절차적 언어, 객체 지향 언어, 함수형 언어, 논리형 언어 등이 있다.
는 말 그대로 절차를 순서대로 작성해 나가는 언어로 C, 포트 등 초기 프로그래밍 언어의 특징이다.
데이터 접근, 데이터 처리와 절차를 하나로 묶어 객체 단위로 관리하는 언어이다.
그래서 데이터와 기능을 한번에 묶어서 처리할 수 있게 되었다. 현대의 언어들은 대부분 객체 지향적 특징을 갖는다. (Java, C++, C# 등)
자바스크립트는 엄밀히 말하면 객체 지향 언어는 아니지만 객체 지향 패턴으로 작성할 수 있다.
C++, Java 등은 클래스를 이용하여 객체를 생성하는 클래스 기반 객체 지향 언어지만 자바스크립트는 클래스가 아닌 프로토타입을 상속하는 프로토타입 기반으로 작성할 수 있다.
자바스크립트에서는 객체를 생성한 후에도 프로퍼티와 메서드를 동적으로 추가하거나 삭제 할 수 있다는게 다른 객체 지향언어와 다른 점이다.
객체지향 프로그래밍의 약자(Object Oriented Programming)이며, 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그램을 여러개의 '객체'로 나눠 객체들 간의 상호작용을 통해 로직을 짜는 방법이다.
객체는 한번 만들고 나면, 메모리상에서 반환되기 전까지 객체 내의 모든 것이 유지된다.
객체를 생성하기 위한 청사진이다. 집단에 공통적으로 속하는 속성과 기능을 변수와 메서드로 가지고 있다.
위 그림처럼 자동차에는 색상, 가격, 속력 등과 같은 고유의 속성이 존재하고, 후진, 전진, 멈춤과 같이 자동차의 기능이 메서드로 존재한다.
사실 인스턴스는 객체이다. 클래스를 통해 만들어진 객체를 부르기 위한 명칭으로 인스턴스라한다.
클래스에 정의한 행위를 수행할 수 있으며, 자신만의 고유 속성도 가질 수 있다.
인스턴스가 실제 프로그램에서 사용되는 데이터라 볼 수 있다.
생성자는 new 연산자와 함께 사용하여 객체를 생성하는 함수이다. 생성자를 사용하면 이름이 같은 메서드와 프로퍼티를 가진 객체를 효율적으로 여러 개 생성할 수 있다.
클래스는 객체를 만들기 위한 생성자 함수(constructor)를 포함한다.
- Encapsulation(캡슐화)
- Inheritance(상속)
- Abstraction(추상화)
- Polymorphism(다형성)
캡슐화는 클로저 모듈패턴을 사용해서 할 수 있다. counter의 value값이 바깥으로 노출되지 않는 형태로 만들어 줄 수 있다.
function makeCounter() {
let value = 0
return {
increase: function() {
value++
},
decrease: function() {
value--
},
getValue: function() {
return value;
}
}
}
counter1
에 makeCounter() 함수를 할당해주면 키 값으로 함수를 갖는 객체를 갖게된다.
직접 value
에 접근하지 않고, increase(), decrease(), getValue()함수를 통해 value
에 접근할 수 있다. 그래서 counter1.value
를 찍더라도 value
값이 노출되지 않는다.
반면에 class 키워드를 사용한 캡슐화는 가능은 하지만 JavaScript 특성 상, 인스턴스에 묶인 모든 속성에 직접 접근이 가능하기 때문에 value값이 완전히 은닉되지 않는다.
class Counter {
constructor() {
this.value = 0;
}
increase() {
this.value++;
}
decrease() {
this.value--;
}
getValue() {
return this.value;
}
}
new 연산자로 Counter의 생성자 함수를 부르면 counter2
에는 value
를 키로 갖는 객체가 할당된다.
그렇기 때문에 getValue()로 value
값을 가져 올 수도 있지만, counter2.value
로 직접 조회하더라도 value
값을 가져올 수 있다.
실제 우리가 사용하는 폰 내부에는 칩, 카메라, 마이크 등 여러 부품으로 내부 구현이 되어 있지만 실제로 상용할 때는 이런 부품들을 생각하지 않고, 화면을 터치하여 기능들을 작동시킬 수 있는 것처럼 인터페이스(interface)를 단순화 할 수 있다.
캡슐화는 코드나 데이터 은닉에 주요점을 둔다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메서드 등을 노출시키지 않고, 기능 단순한 이름으로 정의하는 것에 주요점을 둔다.
인터페이스? 클래스 정의 시, 메서드와 속성만을 정의한것이다. 이것이 추상화의 본질!
mini(자식클래스)의 본질은 Car(부모클래스)이고, mini가 출시일을 따로 갖듯이 자식클래스는 물려받는 속성 기능 외에 속성과 기능을 따로 가질 수도 있다.
하나의 메서드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것을 의미한다.
동일한 메소드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.
class Animal {
speak() {
성대를 이용한다.
}
}
class Human extends Animal {
speak() {
super.speak()
// 복잡한 어휘력
}
}
class Dog extends Animal {
speak() {
super.speak()
// 단순한 어휘력
}
}
동물들을 제 각기 다른 소리를 내는것 처럼 객체 역시 똑같은 메서드라 하더라도 다른 방식으로 구현될 수 있다.
다형성을 제공하지 않는 다면, 부모 클래스에 종류별로 분리해서 하나씩 다 다르게 만들어줘야하는 번거로운 일이 생긴다.