[TIL 1/17] JavaScript OOP

Song-YunMin·2021년 1월 17일
0

TIL

목록 보기
1/29
post-thumbnail

Javascript OOP

Today I Learned 를 Velog 에다 작성하는게 좋을 것 같아 여기다가 작성하려고 한다. 오늘은 주말이지만 자바스크립트 OOP에 대해 학습하였고, 사실 개인적인 견해로는 자바스크립트는 객체지향이 불가한 언어라고 생각하고 있었다. 하지만 여러가지 방법으로 수행할 수 있었고 그 내용에 대해 기록하고 공유하고자 한다.
개인적으로 이 시리즈는 혼자 볼 예정이니 정리가 좀 안되어 있을 수도..! 있다..!

오늘 학습한 내용

Constuctor

Constuctor 는 생성자 라는 이름으로 일반적으로 불린다. 이러한 생성자는 다양하게 필요할 경우가 많다. 같은 기능을 하는 여러개의 메서드를 객체화 하거나 메서드의 인자가 각각 다르게 필요할 경우 파라미터를 정의하고 생성자를 이용하여 각각 다르게 초기화 할 수 있다.

소스코드

function Person(name, first, second, third) {
    this.name  = name;
    this.first = first;
    this.second = second
    this.third = third;
    this.sum = function () {
        return this.first + this.second + this.third;
    }
}

let kim = new Person('kim',10,20,30);
let lee = new Person('lee',10,10,10);
console.log("kim.sum()", kim.sum());
console.log("lee.sum()", lee.sum());

let d1 = new Date('2019-4-10');
console.log('d1.getFullYear()', d1.getFullYear());
console.log('d1.getMonth()', d1.getMonth());        // 0부터 시작하기로 약속되어있음

console.log('date', Date);

console.log('Person()', Person());
// constructor
console.log('new Person()', new Person());      // 생성자 함수(인스턴스)

ProtyType이란?

Prototype은 (원형) 이란 뜻이며, 자바스크립트의 중고급 수준까지 올라가기 위해 필수적인 문법이다. 이러한 Prototype을 이용하여 재사용성이 높은 코드를 작성할 수 있다.

자바스크립트는 Prototype Based Language 이라고도 불린다.

소스코드

function Person(name, first, second, third) {
    this.name  = name;
    this.first = first;
    this.second = second
    this.third = third;

}
// 한번만 정의됨 : 성능 절약
Person.prototype.sum = function () {
    return 'modified : ' + (this.first + this.second + this.third);
}

let kim = new Person('kim',10,20,30);
kim.sum = function(){   // kim 만 동작을 다르게 정의할 수 있음
    return 'this : ' + (this.first+this.second+this.third);
}

let lee = new Person('lee',10,10,10);

console.log("kim.sum()", kim.sum());    // this : 60
console.log("lee.sum()", lee.sum());    // modified : 30

함수 Person 을 만들고 생성자를 이용하여 초기화 한다.

그 후에 메소드 sum 을 protytype(원형) 으로 정의하여 위와 같이 사용할 수 있다.

Person의 인스턴스인 kim 을 보면 동작 방식을 따로 바꿔서 사용할 수 도 있다.

장점

  • 재사용성을 많이 높일 수 있다.
  • 메소드 사용 용도를 쉽게 바꿀 수 있다.

단점

  • 문법이 좀 복잡하고 직관성이 떨어진다.

Class?

클래스는 대표적으로 자바, PHP, Python 등에서도 지원을 하는데, 자바스크립트는 원래 지원하지 않았다. 원래는 constructor 함수를 통해서 객체를 찍어냈었다.

Class 라는 문법이 ES6(ECMAScript) 부터 업데이트 되며 조금 더 손쉽게 객체지향을 구현할 수 있게 되었다.

클래스라는 문법을 제공하는 브라우저 참고는 아래 사이트에서 하면 된다.

Can I use... Support tables for HTML5, CSS3, etc

그리고 현재 최신코드를 예전 문법으로 보게 하는 사이트가 있다. 이 사이트는 아래와 같다.

Babel · The compiler for next generation JavaScript

소스코드

class Person{
    // 객체에 해당하는 메서드를 만들때?
    constructor(name, first, second){      // 생성자
        this.name = name;
        this.first = first;
        this.second = second;
    }
    // 한번만 정의됨 : 성능 절약
    sum() {
        return 'prototype : ' + (this.first + this.second);
    }
}

let kim = new Person('kim',10 ,20);
kim.sum = function(){   // kim 만 동작을 다르게 정의할 수 있음
    return 'this : ' + (this.first+this.second);
}

let lee = new Person('lee',10,10);
console.log("kim.sum()", kim.sum());    // kim.sum() this : 30
console.log("lee.sum()", lee.sum());    // lee.sum() prototype : 20

장점

  • 기존 객체지향 언어와 비슷한 문법으로 쉽게 접근이 가능하다

Inheritance?

상속은 기존 클래스에 있는 기능들을 다른 클래스를 만들어 기존 클래스에 있는 기능을 그대로 가져오는 것을 의미한다.

상속의 필요성은 기존 클래스에 있는 기능에서 추가적으로 만들고 싶은 기능이 있다고 가정하자.

기존 클래스에 기능을 추가하는 방법이 있지만 기존 클래스가 내가 만든 코드가 아니라던가 라이브러리라면 업데이트가 되었을때 내가 작업한 부분이 있기 때문에 업데이트를 못하는 상황에 빠질 수 있다.

남이 작성한게 아니라고 하더라도 내가 만들고 싶은 기능이 기존 클래스에서 거의 사용할 일이 없다고 하면 부담스러운 작업일 수 있다.

위 같은 경우에 상속을 사용할 수있다.

또한 다른 언어와 다르게 부모 클래스를 상속받는 것과 다르게 자바스크립트는 부모객체(인스턴스)를 직접 상속 받을 수 있다.

소스코드

class Person {
    // 객체에 해당하는 메서드를 만들때?
    constructor(name, first, second) {      // 생성자
        this.name = name;
        this.first = first;
        this.second = second;
    }

    // 한번만 정의됨 : 성능 절약
    sum() {
        return this.first + this.second;
    }
}

class PersonPlus extends Person {    // Person 클래스 상속
    constructor(name, first, second, third) {
        super(name, first, second);     // 부모 클래스 요소 초기화
        this.third = third;
    }
    // 부모 클래스의 sum메소드를 사용
    sum() {
        return super.sum() + this.third;
    }
    avg() {
        return (super.sum() + this.third) / 3;
    }
}

let kim = new PersonPlus('kim', 10, 20, 30);

console.log("kim.sum()", kim.sum());
console.log("kim.avg()", kim.avg());

proto?

이 문법을 사용하여 손쉽게 상속을 받는 방법도 있다. 아래 소스코드를 참고해보면, subObj 객체에다가 suberObj 객체를 대입하는 것이다. 이는 상속한 것과 결과가 같으며 아래 subObj 에서 superVal 을 접근하여 출력하는 것을 보면 쉽게 파악할 수 있다.

소스코드

let superObj = {superVal:'super'};
let subObj = {subVal : 'sub'};
subObj.__proto__ = superObj;        // subObj가 superObj의 자식임을 선언
console.log('subObj.subVal => ', subObj.subVal);
console.log('subObj.superVal => ', subObj.superVal);

// 변경을 시도하지만 아래 코드는 객체를 바꾼게 아님
subObj.superVal = 'sub';
console.log('superObj.superVal => ', superObj.superVal);  // superObj.superVal => super

Object.create()?

proto 를 대체할 수 있는 객체이다. proto 문법보단 훨씬 직관적이고 작성하기도 편하므로 권장되는 방법이다.

소스 코드

let superObj = {superVal:'super'};
// let subObj = {subVal : 'sub'};
// subObj.__proto__ = superObj;        // subObj가 superObj의 자식임을 선언
let subObj = Object.create(superObj);       // __proto__ 보다 object.create가 더 좋음
subObj.subVal='sub';
console.log('subObj.subVal => ', subObj.subVal);
console.log('subObj.superVal => ', subObj.superVal);

// 변경을 시도하지만 아래 코드는 객체를 바꾼게 아님
subObj.superVal = 'sub';
console.log('superObj.superVal => ', superObj.superVal);  // superObj.superVal => super
profile
고독한 서버 개발 3년차

0개의 댓글