이번 시간에는 Javascript는 객체지향 프로그래밍인가 + 함수형 프로그래밍과
객체지향 프로그래밍 (OOTP)에 대해 알아보도록 하겠습니다.!
이번 시간에 가장 중요한 면접 질문일 수 도 있습니다!!
1. 함수형 프로그래밍이란?
함수형 프로그래밍은 명령형 프로그래밍에 속합니다.
무엇을 구현하겠다를 초점을 두어, 자료 처리를 수학적인 함수의 계산으로 취급해
상태(state)와 가변적인 데이터(variable data)를 배제하는 프로그래밍 입니다.(선언형)
실행 순서를 지정할 필요가 없기 떄문에 비절차형 언어(non-procedural language)라고도 합니다.
- 함수형의 중요한 개념인 순수함수
- 동일한 input에는 항상 같은 output을 반환한다.
- 함수의 실행이 프로그래밍에 영향을 주진 않는다.
- 순수함수의 예를 들어보자
function add(a,) {
return a + b;
}
console.log( add(10,5) ); // 출력값 15
함수 add는 순수함수이다.
✅ 그렇다면 순수함수가 아닌 것은?
let c = 10;
function add2(a, b) {
return a + b + c;
}
console.log( add2(10 , 2) ); //출력값 22
console.log( add2(10 , 3) ); //출력값 23
console.log( add2(10 , 4) ); //출력값 24
c = 20;
console.log( add2(10 , 2) ); //출력값 32
console.log( add2(10 , 3) ); //출력값 33
console.log( add2(10 , 4) ); //출력값 34
출처 : yoonscode.com/javascript-functional-programing-01/
2. 객체지향 프로그래밍 (Object Oriented Programming)
객체 중심적 사고이며, 데이터를 추상화해 상태(state)와 행위(Act)를 가진 객체를 만들고,
객체 간 유기적인 상호작용을 통한 로직을 구성하는 프로그래밍 방법입니다.
자바스크립트에서 객체를 정의하는 방법은 매우 많은데 그중 function 키워드를 이용한 객체 정의 방법이 있다.
주의할 점은 function 키워드를 이용한다 해도 function이 아니라는 것이다.
아래 [코드1]은 자바스크립트 function키워드를 이용한 Person이라는 객체를 정의한 것이다. [코드 1]에 정의된 Person 객체는 맴버 변수로 fullName,gender, age라는 변수를 갖고 있다.
2-1. Person을 이용한 객체 접근
function Person(fullName, gender, age) {
this.fullName = fullName;
this.gender = gender;
this.age = age
}
[코드1] Person 객체 정의 1
C++, Java의 클래스 정의와 약간 다른 점은 생성자를 정의하지 않고 함수에 인자를 전달하는 방식으로 객체를 선언하면 객체의 선언 자체가 생성자의 역할을 한다는 것. 아래 [코드 2]는 위에서 정의한 Person 객체를 선언한뒤, 맴버 변수에 접근하는 코드이다.
var person1 = new Person('ronaldo', 'man', 35);
console.log(person1.fullName);
console.log(person1.gender);
console.log(person1.age);
[코드 2]Person 객체 접근
결과
2-2. 맴버 함수
자바스크립트에서 객체의 맴버 함수를 정의하는 방법은 매우 다양하다. 이 글에서 객체의 prototype 속성을 이용해 맴버 함수를 정의하는 방법을 설명하고 있다. 아래 [코드 3]은 Person 객체에 맴버 변수의 값을 모두 출력하는 showInfo()라는
맴버 함수를 정의하는 것 이다.
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);
}
[코드 3] Person 객체 정의 2
Person 객체의 맴버 함수 showInfo()는 아래 [코드 4]와 같이 호출할 수 있다. [코드 4]를 실행하면, 브라우저의 콘솔창에는 name1,man,25 가 출력되는 것을 볼 수 있을 것이다.
var person1 = new Person('name1', 'man', 25);
person1.showInfo();
[코드 4] Person 객체의 맴버 함수 showInfo() 호출
결과
맴버 함수를 정의할 때 주의할 점은 객체 자신의 맴버 변수를 접근할 때는 항상 this.맴버 변수의 형태로 접근해야 한다.
2-3. 접근 범위 설정
앞의 [코드 3]과 같이 맴버 변수를 this 포인터를 통해서 선언 시 객체 외부에서도 맴버 변수에 접근이 가능하다. 그러나 때로는 객체에 접근을 제한해야할 필요가 있는데, 전통적인 객체지향 프로그래밍 언어인 C++, Java에서는 private 키워드를 제공해 객체에 접근을 제한시킬 수 있다.자바스크립트 에서도 [코드3]을 약간 수정해주면 private 와 비슷한 키워드로 구현할 수 있다.
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);
}
}
[코드 5] 접근 범위를 제한해 객체 선언
[코드 5]는 Person 객체를 선언하는 코드에 맴버 변수를 this가 아닌, var 키워드를 사용해 정의하고 있다. 자바스크립트에서는 var 키워드를 이용해 맴버 변수를 선언할 경우, 객체 외부에서 참조가 불가능하게 된다. 또한, var 키워드로 정의된 맴버 변수는 propertype으로 정의된 함수에서도 접근이 불가능하기에 맴버 함수 showInfo()를 객체 내부에, 그리고
showInfo()를 객체 외부에서 참조가 가능하도록 this포인터를 이용해 정의하였다. Person 객체를 [코드 5]와 같이
선언 한다면, Person 객체의 맴버 변수는 오직 맴버 함수 showInfo()를 통해서만 출력할 수 있다.
2-4. 객체 상속
객체 기반의 코드를 구현할 때, 가장 핵심이 되는 두 가지 기능을 꼽자면 아마도 접근 범위의 제한과 상속일 것이다. 자바스크립트에서는 객체에 대한 접근 범위의 제한뿐만 아니라, 객체간의 상속 기능도 제공한다. 아래의 [코드6]은
Person 객체를 상속받는 Student객체에 대한 정의 및 Student 객체의 맴버 함수를 실행하는 코드다.
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();
}
[코드 6] Student 객체 정의 및 맴버 함수 실행
[코드 6]에서 1~13번째 줄에서는 Person 객체를, 15~31번째 줄에서는 Student객체를 정의하고 있다. 그 다음 33~38번 줄에서는 Student 객체에 대한 인스턴스 (instance)를 생성해 Student 객체의 맴버 함수인 study()와 showInfo()를 호출하고 있다. 객체의 상속을 위해 추가한 코드와 추가된 코드의 기능은 아래와 같다.
- Person.call(this, fullName, gender, age): 상속받는 Person 객체의 생성자를 호출한다.
- Student.prototype = Object.create(Person.prototype): Student 객체의 prototype를 Person 객체의 prototype로 정의한다.
- Student.prototype.constructor = Student: 현재 Person의 생성자를 참조하고 있는 Student 객체의 생성자를 다시 Student 객체의 생성자로 변경한다.
자바스크립트에서 언어 차원에 protected와 같은 키워드를 제공하지 않기에 여러 기법을 조합해 protected 기능을 ㅜㄱ현 해야한다, 따라서 [코드 6]에서는 코드를 간단하게 구현하기 위해 protected 기능을 따로 구현하지 않고, public과 같은 this 포인터를 이용해 Student에 상속되는 Person의 맴버 변수를 선언하였다.
OOP의 가장 큰 특징 4가지가 있다!
- 추상화 : 공통적인 속성이나 기능을 묶어 이름을 붙이는 것.
- 캡슐화 : 데이터를 은닉하고 데이터 기능을 노출시키지 않는다.
- 상속성: 가장 중요한 특징. 하나의 클래스가 가진 특징(데이터,함수)를 그대로 다른 클래스에 물려줄때 사용된다.
(부모의 메소드나 변수를 사용할 수 있다.) - 다형성: 같은 함수가 있어도 매게변수에 따라서 각자 다른 일을 하는 것.
객체지향 프로그래밍은 모듈 재사용 등으로 인한 확장 및 유지보수에 상대적으로 용이하다.
자바스크립트는 프로토타입 기반으로 객체지향 프로그래밍을 할 수 있다.
👉 프로토타입이란?
자바스크립트의 모든 객체는 프로토타입(prototype)이라는 객체를 가지고 있다.
모든 객체는 그들의 프로토타입으로부터 프로퍼티(property)와 메소드(method)를 상속받는다.
이처럼 자바스크립트의 모든 객체는 최소 하나 이상의 다른 객체로부터 상속 받으면서
이때 상속되는 정보를 제공하는 객체를 프로토타입이라 불린다.
- 프로토타입 예제
const soccerPlayer = function() {};
soccerPlayer.prototype = {
name: String,
age: Number,
height: Number,
weight: Number,
position: String,
team: String
};
const cristiano_ronaldo = new soccerPlayer();
cristiano_ronaldo.name = "cristiano_ronaldo";
cristiano_ronaldo.age = 34;
cristiano_ronaldo.height = 184;
cristiano_ronaldo.weight = 82;
console.log(cristiano_ronaldo);
출처: velog.io/@hidaehyunlee 이대현님 블로그
무슨 차이인지는 모르겠으나, 위의 예제를 설명하자면
soccerPlayer라는 생성자 함수(객체)를 재사용해 이것을 하나의 프로토타입으로써 밑바탕에 깔고 호날두라고 불리는 새로운 객체를 생성한다.
라고 볼수 있다.
생성자 함수 (객체를 생성할 때 최초로 호출되는 함수) 를 통해 생성된 객체들이 공통으로 가지는 속성(프로토타입), 공통으로 가지는 메소드를 저장해놓은 별도의 공간 = 프로토타입 인 것 같다고 한다!
🙊 그래서 자바스크립트는 객체지향? 함수형 ?
자바스크립트는 여러가지 스타일로 프로그래밍이 가능한
멀티 패러다임 언어(multiparadigm programming language) 이다.
명령형 프로그래밍(함수형에 속한)도 가능하고 ,객체지향도 가능하다.
하지만 함수형 프로그래밍의 중요한 개념인 순수함수를 완벽하게 표현(?)을 할 수 없다.
😣 그렇다면 그 둘의 차이는??
객체지향은 객체 안에 상태를 저장하고, 이 상태를 이용해 메소드를 추가하고,
상태변화를 설정하고 조정하기위해 다양한 기능을 사용한다.
이에 반해 함수형은 상태를 제어하는 것보다 상태를 저장하지 않고 없애는데에 포인트를 쥐고 있다.
그래서 함수형은 간결한 프로그래밍에 더 적합하다.
참고
'프론트 엔드 > Javascript' 카테고리의 다른 글
[Javascript] Promise란 ? (0) | 2021.10.13 |
---|---|
[javascript]비동기적 처리(Callback, Promise, Async-Await) (0) | 2021.10.09 |
[javascript] 이벤트 버블링, 캡쳐링, 위임 (0) | 2021.10.09 |