1. 객체지향 프로그래밍이란?
객체지향은 프로그래밍 방법론중에 하나로,
프로그램을 작성할 때 객체들을 만들어 서로 소통하도록하는 방법.
(이와 다르게 순서대로 실행되는것을 절차지향 프로그래밍이라고 한다.)
객체란?
우리가 앞서서 배운 자바스크립트 객체는 데이터의 묶음 이라면
객체 지향의 객체는 우리가 표현하고자 하는 구체적인 사물을 추상적으로 표현한것이다.
즉 한 사람을 객체로 표현한다면
const me = {
name : 'Jason',
address : 'Seoul',
phoneNum : '010-1234-1234',
canWalk : function(){
console.log('Hi,Hello');
}
}
이렇게 표현할 수 있다.
그리고 또한 객체는 행동과 상태를 가진다.
여기서 행동은 메소드, 상태는 프로퍼티라고 할 수 있다.
이렇게 새로운 능력도 부여가 가능합니다.
const me = {
name : 'Jason',
address : 'Seoul',
phoneNum : '010-1234-1234',
canWalk : function(){
console.log('Hi.Hello');
},
teaching : function(student){
student.levelUp();
}
}
그리고 새로운 객체를 만들어봅니다.
const student = {
level: 1,
levelUp : function(){
this.level++;
}
}
이제 마치 게임처럼 이렇게 상호작용을 할 수 있다.
me.teaching(student);
이처럼 객체와 객체가 서로 메소드를 통해 상호작용하게 하는것이 바로 객체지향 프로그래밍입니다.
실습해보기
https://wannabecm.github.io/JSassignment/
1.1 생성자
생성자란 객체를 만들 때 new 연산자와 함께 사용하는 함수입니다.
예시
let myArr = new Array(1,2,3);
이러한 생성자를 내장 생성자라고 합니다.
생성자를 사용하는 이유
생성자의 장점은 생성자를 통해 생성된 객체는 같은 프로퍼티와 메서드를 공유할 수 있다.
let myArr = new Array(1,2,3);
let myArr2 = new Array(4,5,6);
myArr2.length
myArr.length
myArr.forEach(item=>{
console.log(item);
})
myArr2.forEach(item => {
console.log(item);
})
커스텀 생성자 만들어보기
생성자는 함수이기 때문에 기본적으로 함수가 필요합니다.
생성자 함수는 암묵적으로 대문자로 시작하는 이름을 가지는 것으로 약속되어 있습니다.
function Factory(){}
그리고 new 키워드를 통해 객체를 생성합니다.
function Factory(){}
let robot1 = new Factory();
Factory 생성자 함수는 따로 return 값을 가지지 않지만 new키워드가 앞에 붙게되면 실행되었을 때 자동적으로 객체를 생성하고 반환합니다. 이렇게 반환되어 만들어진 객체를 다른 말로 인스턴스(instance) 라고 합니다.
때문에 생성자 함수와 객체의 관계는 instanceof 로 확인 할 수 있습니다.
robot1 instanceof Factory
자 그러면 이제 우리만의 프로퍼티와 메서드를 가진 로봇 객체를 만들어 봅시다.
function NewFactory(name){
this.name = name;
this.sayYourName = function(){
console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
}
}
원래 함수안에서의 this는 함수를 호출한 객체를 참조합니다.
하지만 생성자 함수 앞에 new 연산자가 사용되면 함수안의 this는 생성자가 만들어낸 객체 즉, 인스턴스를 참조합니다.
자 이제 객체 즉, 인스턴스를 생성해 봅시다.
let robot1 = new NewFactory('브랜든');
- 실습 : 음식 이름의 배열을 전달하면 배열안에서 랜덤하게 메뉴를 뽑아내는 로봇객체의 생성자를 만들어보세요.
const foods = ["짜장면", "뽁음밥", "해장국", "치킨"];
function FoodBot(foodNames) {
this.menu = foodNames;
this.sayMenu = function () {
console.log(this.menu[Math.floor(Math.random() * this.menu.length)]);
};
}
const foodBotMark1 = new FoodBot(foods);
이렇듯 우리가 필요에 따라서 배열(Array), 객체(Object)를 사용하는 것 처럼, 우리가 필요할 때 사용할 수 있는 우리만의 객체를 만들어서 사용할 수 있도록 도와주는 것이 바로 생성자입니다.
1.2 프로토타입 (prototype)
자 그런데 문제가 하나 있습니다. 우리는 손쉽게 객체를 생산할 수 있지만,
객체의 메서드를 등록 할때마다 새로운 함수를 생성하고 있습니다.
this.sayYourName = function(){
console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
}
바로 이 부분이 문제입니다. 우리는 100개의 객체를 생성할때마다 역시 100개의 함수를 새로 만들고 있는것 입니다. 이러한 자원의 낭비를 해결하기 위해 등장한 것이 바로 프로토타입입니다.
function NewFactory2(name){
this.name = name;
}
NewFactory2.prototype.sayYourName = function(){
console.log(`삐리비리. 제 이름은 ${this.name}입니다. 주인님.`);
}
이렇듯 프로토타입은 모든 인스턴스가 하나의 메서드를 공유하도록 만들어 자원을 더 효율적으로 사용하도록 도와줍니다. 생성된 객체끼리 메서드를 비교하여 같은 곳을 참조하는지 살펴보는것도 이해하는데 도움이 됩니다.
- 실습: 우리가 만들었던 음식 로봇객체의 메서드를 프로토타입으로 분리해보세요, 그리고 객체의 메서드가 서로 동일한 주소를 참조하는지 확인해보세요.
const foods = ["짜장면", "뽁음밥", "해장국", "치킨"];
function FoodBot(foodNames) {
this.menu = foodNames;
this.sayMenu = function () {
console.log(this.menu[Math.floor(Math.random() * this.menu.length)]);
};
}
const foodBotMark1 = new FoodBot(foods);
- 실습2: 우리가 객체지향 개념에서 만들었던 ‘나’ 와 ‘대상’ 객체를 생성자를 통해서 만들어 볼 수 있도록 코드를 수정해봅시다.
// const me = {
// name: '한재현',
// address: '제주도 제주시 인다 1길',
// phoneNum: '010-8001-6536',
// canWalk: function () {
// console.log('재현이가 걷는다.');
// },
// teaching: function (student) {
// student.levelUp();
// }
// }
// const student = {
// level: 1,
// levelUp: function () {
// this.level++;
// }
// }
function Me(name, address, phoneNum) {
this.name = name;
this.address = address;
this.phoneNum = phoneNum;
}
Me.prototype.canWalk = function () {
console.log("재현이가 걷는다.");
};
Me.prototype.teaching = function (student) {
student.levelUp();
};
function Student(level) {
this.level = level;
}
Student.prototype.levelUp = function () {
this.level++;
};
1.3 객체의 상속
이미 CSS 에서 익숙하게 다루었던 상속이라는 개념은 자바스크립트에서도 존재합니다.
이번 시간에는 자바스크립트에서 상속이 어떤 식으로 일어나는지 알아보겠습니다.
function Parent() {
this.name = '재현';
}
Parent.prototype.rename = function (name) {
this.name = name;
}
Parent.prototype.sayName = function () {
console.log(this.name);
}
먼저 부모의 역할을 할 생성자 함수를 만들고 자식 역할의 생성자 함수를 만듭니다.
function Child() {
Parent.call(this);
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.canWalk = function () {
console.log('now i can walk!!');
}
위의 코드에서 call 함수는 Child 함수의 this가 Parent 생성자 함수의 this를 바라보게 만듭니다. 즉, Child 를 통해 생성된 인스턴스의 this 가 Parent 함수안의 프로퍼티에 접근할 수 있게합니다.
그리고 Object.create 함수는 주어진 인자를 Child.prototype에 연결하는 역할을 합니다. 즉 Parent 객체의 프로토타입을 Child 객체의 프로토타입이 참조하게 합니다.
위의 두 가지 과정을 통해 Child 객체는 Parent 객체의 모든 것을 상속받게 됩니다.
'멋쟁이사자처럼FE 2기 > TIL' 카테고리의 다른 글
웹 최적화(Optimization) (0) | 2022.05.19 |
---|---|
스코프&클래스(Class) (0) | 2022.05.18 |
20일차_Sass(1) (4) | 2022.04.25 |
SVG로 지도 만들기 (0) | 2022.04.21 |
유용한 디자인 사이트 모음 (0) | 2022.04.21 |