[CodeStates-Section2]U2.JavaScript 객체 지향 프로그래밍

hameee·2022년 11월 21일
0

CodeStates_Frontend_42기

목록 보기
15/39

1.후기

 저번 달에 객체지향, 프로토타입을 파다 이해가 어려워 포기한 적이 있다. 그래서 이번 수업에 잔뜩 겁을 먹고 있었다. 하지만 다시 보니 단어도 친숙해져 있고 눈에 들어오지 않았던 것이 보여 이해하는 데 성공했다!!! 역시 예습이 답이라고 생각했다. 내일 내용도 미리 보기 위해 Unit3에 들어가 보았다. ...비동기? 하나도 모르겠다. 산 넘어 산이다. 내일도 열심히 머리를 굴려봐야겠다.

2.새롭게 알게 된 것

Unit2 - JavaScript 객체 지향 프로그래밍
Chapter1. 객체 지향
 -1. 클로저 모듈 패턴
 -2. 클래스와 인스턴스
 -3. 객체 지향 프로그래밍
 -4. 객체 지향 차이점

Chapter2. Prototype
 -1. 프로토타입과 클래스
 -2. 프로토타입 체인

<Ch1. 객체 지향>

1. 클로저 모듈 패턴
1) 객체 지향 프로그래밍(OOP, Object-oriented programming)
절차 지향 프로그래밍과는 다르게 데이터와 기능을 한 곳에 묶어서 처리

주의. 객체지향이 무조건 좋은 것은 아님
메모리 관리가 중요하다면? -> 메모리를 적게 쓰는 절차 지향
사람들과의 협업이 중요하다면? -> 코드 이해가 쉬운 객체 지향

2) 메서드 호출 방식 이용 시 화살표 함수를 사용 불가
참고. 화살표 함수의 제한점
this나 super에 대한 바인딩이 없고, methods로 사용될 수 없음
new.target 키워드에 접근 불가
일반적으로 스코프를 지정할 때 사용하는 call, apply, bind methods를 이용할 수 없음
생성자(Constructor)로 사용할 수 없음
yield를 화살표 함수 내부에서 사용할 수 없음

3) 클로저 모듈 패턴 사용 이유 -> 재사용을 위해
똑같은 기능을 하는 인스턴스 객체를 여러 개 만들어 재사용할 수 있음

2. 클래스와 인스턴스
1)
class -> 자동차 청사진
instance -> 청사진을 바탕으로 한 객체(객체 안에 포함되는 개념)

출처:http://www.w3big.com/ko/php/php-oop.html#gsc.tab=0

2) 새로운 인스턴스를 만드는 법: new
클래스는 인스턴스를 찍어냄

참고.
class 이름: 대문자 시작, 일반명사
일반적인 함수 이름: 소문자 시작, 동사 포함

3) 클래스를 만드는 법: 함수로 정의(es5), class(es6)

//ES5: 함수로 정의
//function이 생성자 함수
function Car(brand, name, color) {
	// 인스턴스가 만들어질 때 실행되는 코드
}
//ES6: class 이용해 정의
class Car {
  	//constructor가 생성자 함수
	constructor(brand, name, color) {
    // 인스턴스가 만들어질 때 실행되는 코드
    }
}

참고. 생성자 함수 특징
함수 이름의 첫 글자는 대문자로 시작
반드시 'new' 연산자를 붙여 실행

4) 인스턴스 만드는 법: new 키워드

let avante = new Car('hyundai', 'avante', 'black');
let mini = new Car('bmw', 'mini', 'white');
let beetles = new Car('volkswangen', 'beetles', 'red');

new가 사용되면
-> 생성자 함수 실행
-> 변수(avante, mini, beetles)에 인스턴스 할당
-> 클래스(Car)의 고유 속성과 메소드 가짐

5) 속성과 메소드
클래스 -> 속성, 메소드 정의
인스턴스 -> 속성, 메소드 이용

자동차 예시.
속성: 브랜드, 차 이름, 색상, 현재 연료 상태, 최고 속력 등
메소드(객체에 딸린 함수): 연료 주입, 속력 설정, 운전 등

6) 속성을 정의하는 법: this 이용

//ES5
function Car(brand, name, color) {
	this.brand = brand; // 인스턴스의 brand 속성을 파라미터 brand의 인자 값으로 할당
  	this.name = name;
  	this.color = color;
}
//ES6
class Car {
	constructor(brand, name, color) {
		this.brand = brand;
  		this.name = name;
  		this.color = color;
    }
}

파라미터 값: 인스턴스 생성 시 지정하는 값
this: 인스턴스 객체를 의미
this에 할당한다는 것: 만들어진 인스턴스에 해당 브랜드, 이름, 색상을 부여하겠다는 의미

참고.

7) 메소드를 정의하는 법: 함수 밖에서 prototype(es5), 함수 안에 삽입(es6)

// ES5: 함수 밖, prototype 이용
function Car(brand, name, color) { /* 생략 */ }

Car.prototype.refuel = function () {
	// 연료 공급을 구현하는 코드
}

Car.prototype.drive = function() {
	// 운전을 구현하는 코드
}

// ES6: 함수 안
class Car(brand, name, color) {
	constructor(brand, name, color) { /* 생략 */ }
	
  	refuel() {
     	// 연료 공급을 구현하는 코드
    }
  
  	drive() {
    	// 운전을 구현하는 코드
    }
}

참고. constructor도 메서드
class로 생성된 객체를 생성하고 초기화하기 위한 특수한 메서드
return 없음
클래스 안에 한 개만 존재할 수 있음

8) 인스턴스에서 속성, 메소드 사용법

class Car {
  constructor(brand, name, color) {
    this.brand = brand;
    this.name = name;
    this.color = color;
  }

  refuel() {
    console.log(this.name + '에 연료를 공급합니다');
  }

  drive() {
    console.log(this.name + '가 운전을 시작합니다');
  }
}

let avante = new Car('hyundai', 'avante', 'black');
console.log(avante.color); //black
console.log(avante.refuel()); //avante에 연료를 공급합니다

9) JavaScript에서만 유효한 용어 사전

10)

참고. 프로토타입 메소드, 정적 메소드
class 안에 정의된 메소드는 프로토타입 메소드 ---> 인스턴스에서 호출
앞에 static을 붙이면 정적 메소드 ---> 클래스에서 호출

11) 배열 정의 = Array라는 클래스의 instance를 만드는 것

// 자동차 예시
let avante = new Car('hyundai', 'avante', 'black');
avante.color;// 'black'
avante.drive();// 아반떼가 운전을 시작합니다

// 평소 배열 정의
let arr = ['code', 'states', 'pre'];
arr.length;// 3
arr.push('course');// 새 element를 추가합니다

// 사실은 배열 정의도 클래스의 인스턴스 생성
// class: Array
// instance: arr
// length, push: Array prototype object의 메소드
let arr = new Array('code', 'states', 'pre');
arr.length;// 3
arr.push('course');// 새 element를 추가합니다

지금까지 만들었던 배열: class Array의 instance object
length, push -> class Array의 prototype에 정의된 메소드

12) 실습

class Counter {
  constructor() {
    //왜 파라미터가 없지: 인스턴스 생성 시 지정하는 값이 필요 없으므로
    this.value = 0; //this는 Counter가 아닌 counter1을 가리킴
  }

  increase() {
    this.value++;
  }

  decrease() {
    this.value--;
  }

  getValue() {
    return this.value; //왜 여기만 return 있지
  }
}

let counter1 = new Counter();
counter1.increase();
counter1.increase();
console.log(counter1.getValue()); //2

3. 객체 지향 프로그래밍
1) 객체 지향 프로그래밍 이전
절차 지향 프로그래밍 존재
절차적 언어는 순차적인 명령의 조합

2) 객체 지향 프로그래밍 등장
데이터(속성)와 기능(메소드)을 별개로 취급하지 않고, 한 번에 묶어서 처리
(속성과 메소드가 같이 클래스에서 정의됨)

3) OOP(Object Oriented Programming)
프로그램 설계 철학
모든 것을 '객체'로 그룹화
재사용성(캡슐화, 추상화, 상속화, 다형성을 통해 얻을 수 있음)

4) 클래스와 인스턴스

5) OOP Basic Concepts
-Encapsulation(캡슐화)
속성과 메서드를 하나의 객체 안에 넣어 묶음
실제 구현 내용 일부를 내부에 감추어 은닉 -> 유지보수, 수정 용이
느슨한 결합 -> 불필요한 코드 변경 줄임, 재사용성 높임

-Inheritance(상속)
부모 클래스의 특징을 자식 클래스가 물려받는 것
기본 클래스(base class)의 특징을 파생 클래스(derived class)가 상속 받음
-> 코드 중복 줄임

-Abstraction(추상화)
내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만듦
->인터페이스가 단순
->너무 많은 기능들이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있음

-Polymorphism(다형성)
같은 메서드라 하더라도, 다른 방식으로 구현될 수 있음
ex. render() 메서드는 TextBox, Select, CheckBox에서 다르게 렌더링

참고. 캡슐화, 추상화
캡슐화 예시 -> 클래스에 속성과 메소드를 같이 담는 것
추상화 예시 -> 클래스에 이름을 설정하는 것

참고 사이트(캡슐화): https://bperhaps.tistory.com/entry/%EC%BA%A1%EC%8A%90%ED%99%94%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-%EC%96%B4%EB%96%A4-%EC%9D%B4%EC%A0%90%EC%9D%B4-%EC%9E%88%EB%8A%94%EA%B0%80
참고 사이트(느슨한 결합): https://taesan94.tistory.com/85

4. 객체 지향 차이점
1) javascript는 private, interface 키워드 없음(TypeScript에 존재)
prive -> 은닉화 관련
interface -> 추상화 관련

<Ch2. Prototype>

1. 프로토타입과 클래스
1) 인스턴스, 생성자 함수, 프로토타입 객체, Object Prototype Object, function Object() {}의 관계

-객체는 언제나 함수로부터 나옴
-함수를 정의하면 함수와 함수의 프로토타입 객체가 생성
-prototype: 함수에 존재, 프로토타입 객체를 가리킴
-constructor: 프로토타입 객체에 존재, 함수를 가리킴
-__proto__: 모든 객체(인스턴스, 프로토타입 객체)에 존재, 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킴
참고자료(프로토타입): https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

2. 프로토타입 체인
1) extends, super
-extends
class 자식클래스 extends 부모클래스: 클래스를 다른 클래스의 자식으로 만들기 위해 class 선언 또는 class 식에 사용

-super()
constructor 안에서 super(물려받을 속성): 부모 클래스의 생성자 호출, super()의 매개변수를 통해 상위 클래스의 멤버를 상속받을 수 있음. this 전에 써주어야 함, 한 번만 사용될 수 있음.
constructor 밖에서 super.부모 클래스 함수: 부모 클래스 함수에 접근

//부모 클래스
class Person {
  constructor(first, last, age, gender, interests) {
    this.name = {
      first,
      last
    };
    this.age = age;
    this.gender = gender;
    this.interests = interests;
  }

  greeting() {
    console.log(`Hi! I'm ${this.name.first}`);
  };

  farewell() {
    console.log(`${this.name.first} has left the building. Bye for now!`);
  };
}

//자식 클래스
class Teacher extends Person {
  constructor(first, last, age, gender, interests, subject, grade) {
    super(first, last, age, gender, interests);

    // subject and grade are specific to Teacher
    this.subject = subject;
    this.grade = grade;
  }
}

//결과: 상속 가능
let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5);
snape.greeting(); // Hi! I'm Severus.
snape.farewell(); // Severus has left the building. Bye for now.
snape.age // 58
snape.subject; // Dark arts

주의.
constructor 안의 속성, constructor 밖의 매소드 모두 Person.prototype에 저장됨

참고 사이트: https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Classes_in_JavaScript#ecmascript_2015_%ED%81%B4%EB%9E%98%EC%8A%A4

2) DOM에서 div와 프로토타입
-div 엘리먼트의 상속 관계
Object <- EventTarget <- Node <- Element <- HTMLElement <- HTMLDivElement <- div

__proto__가 6개 붙은 것은 Object.prototype(Object 함수의 프로토타입 객체) 나옴

3) 프로토타입 체인

주의.
-함수.prototype은 함수의 상위를 가리키는 것이 아님(생성자 함수와 함수의 프로토타입 객체는 동등)
-하위 클래스와 인스턴스는 다른 개념
생성자함수.prototype -> 자신의 프로토타입 객체(동등)
객체.__proto__-> 인스턴스라면 본인의 조상 함수의 프로토타입 객체, 프로토타입 객체라면 상위 클래스의 프로토타입 객체 의미(상위, 프로토타입 체인과 관련)

0개의 댓글