TIL(20.03.19) 자바스크립트 OOP,Prototype

이민택·2020년 3월 19일
0

TIL

목록 보기
25/44

객체 지향 프로그래밍(Object Oriented Programming)

객체 지향 프로그래밍이란 프로그래밍 방법론 중에 하나로써 프로그램 설계를 객체 위주 즉 프로그램의 모든 부분을 객체로 세분화 해서 설계가 되는 것이 특징이다

  • 절차 지향 언어

    • 절차 지향 언어란 프로그램 실행 단계가 일정한 순서를 가지고 실행되는 것을 지향하는 언어이다
    • 대표적으로 c,cobol,fortran등이 있다
  • 객체 지향 언어

    • 객체 지향 언어란 프로그램 실행 단계가 객체 위주로 실행되는 것을 지향하는 프로그래밍 언어를 말한다
    • 대표적으로 java, c++, c#, pyhon, javascript 등이 있다

객체 지향 프로그래밍의 특징

객체 지향 프로그래밍은 일반적으로 클래스라는 것이 있다 이는 새로운 객체(인스턴스)를 찍어내는 설계도라고 생각하면 편하다 이 설계도를 가지고 찍어낸 인스턴스들은 클래스의 속성과 메소드를 가지고 있는 특징이 있다

속성 ,메소드

클래스에서 속성은 그 클래스의 정보를 나타낸다 예를 들어 자동차의 정보로 속도,색깔,브랜드 등이 있을 수 있다

메소드는 그 클래스의 동작을 나타낸다 같은 예시로 자동차가 출발한다, 멈춘다, 속도를 올린다 등이 있을 수 있다

객체 지향 프로그래밍의 기본 컨셉

Encapsulation (캡슐화)

클래스의 속성과 메소드를 다시 정의하지 않고 새로운 인스턴스를 만들어 낼 때 다시 사용할 수 있다는 특징이다 개발자는 클래스의 모든 정보를 캡슐 처럼 인스턴스에 전달 할 수 있기 때문에 이런 속성을 가진다

  • 코드의 재사용성이 증가한다
  • 복잡성이 낮아 진다

Inheritance(상속성)

클래스의 정보를 다른 클래스의 전달할 수 있다 이를 상속성이라 표현한다 클래스의 정보를 전달 받은 클래스를 형식적으로 자식 클래스 전달 해준 클래스를 부모 클래스 라고 한다 자식 클래스는 부모의 속성과 메소드를 다시 정의하지 않고 사용이 가능하다

  • 불필요한 코드를 제거한다

Abstraction(추상화)

추상화 특징은 클래스를 사용하는 개발자가 클래스 내부 메소드의 구현이 어떻게 되었는지 알지 못해도 인스턴스를 만들어서 사용할 수 있게 해주는 특징이다

예를 들어 전화기 클래스의 call 메소드가 있다고 가정하면 이 클래스를 사용하는 개발자는 새로운 전화기 인스턴스를 만들어서 call 메소드를 호출하면 되는 것이다 이 과정에서 call 메소드의 내부적인 구현을 몰라도 사용이 가능하다

  • 인터페이스를 간단하게 해준다
  • 변화의 영향이 줄어든다

Polymorphism(다형성)

다형성 특징은 상속성과 비슷하지만 다른게 작동한다 다형성을 통해 구현된 자식 클래스는 부모클래스의 메소드를 그대로 받아 들이지 않고 자신의 정보를 이용하여 메소드를 수정할 수 있는 방식이다

위 그림의 예로 들어 일반적인 동물 클래스를 부모클래스라 하고 부모클래스 내부의 speak라는 메소드가 구현이 되어있다 이를 각기 다른 동물에게 상속해주면서 여러 동물들은 자신의 속성을 이용해 speak 메소드를 실행한다

  • 하나의 클래스에 대한 다양한 구현을 깔끔하게 해준다

JavaScript에서 object를 생성하는 방식

자바스크립트에서 클래스를 사용하는 방법은 두가지가 있다 하나는 es5까지 사용한 함수 선언과 비슷한 방식과 다른 하나는 es6에서 새롭게 추가된 class 키워드를 이용하는 방식이다

    //ES5
    function PersoneEs5(name,age){
        this.name=name;
        this.age=age;
    
    
        PersoneEs5.prototype.meal=function(){
            console.log('식사를 합니다');
        }
    
        PersoneEs5.prototype.sleep=function(){
            console.log(name+'이 잠을 잡니다');
        }
    }
    //ES6
    class PersoneEs6{
        constructor(name,age){
            this.name=name;
            this.age=age;
        }
    
    
        meal=function(){
            console.log('식사를 합니다');
        }
    
        sleep=function(){
            console.log(this.name+'이 잠을 잡니다');
        }
    }

위와 같이 클래스를 사용하기 전에 사용하던 4가지 방식이 있다

Instantiation Patterns

1.Functional

    var Car=function(position){
    	var someInstance = {};
    	someInstance.position=position;
    	someInstance.move=function(){
    		this.position+=1;
    	}
    	return someInstance;
    }
    var car1=Car(5); 

이와 같이 함수 내부에 객체를 생성해서 리턴하는 방식이다 그래서 함수 호출만 해주면 인스턴스가 생성이 된다

2.Functional Shared

    var extend = function(to, from){
    	for ( var key in from) {
    		to[key] = from[key];
    	}
    };
    
    var someMethods= {};
    someMethods.move = function(){
    		this.position+=1;
    };
    
    var Car=function(position){
    	var someInstance = {
    		position: position;
    	};
    	extend(someInstance, someMethod);
    	return someInstance;
    }
    var car1=Car(5); 

이 방식은 함수 밖에서 메소드를 정의해서 인스턴스를 반환하기 전에 합쳐주는 방식이다. 이 방식을 사용하는 이유는 Functional 방식은 모든 인스턴스에게 메소드를 할당하기 때문에 메모리를 많이 먹는다

그러나 위와 같이 하면 someMethods라는 주소만 사용하기 때문에 메모리 효율이 좋아진다.

3.Functional Prototypal

    var someMethods= {};
    someMethods.move = function(){
    		this.position+=1;
    };
    
    var Car=function(position){
    	var someInstance = Object.create(someMethods);
    	someInstance.position = position;
    	return someInstance;
    }
    var car1=Car(5); 

2번쨰 방식보다 훨씬 간단한 방식이다 object.create는 특정 객체를 프로토타입으로 하는 객체를 생성해준다

4.Functional Pseudoclassical

    var Car = function(position) {
    	this.position = position;
    };
    
    Car.prototype.move = function() {
    	this.position +=1;
    };
    
    var car1 = new Car(5);

이 방식은 직접 프로토타입을 이용하여 작성하는 방식이다 제일 간다하고 많이 쓰인다 위에 코드에서 보면 인스턴스를 생성할 때 new 연산자를 이요하는 것을 알 수 있다

Prototype( 프로토타입 )

위 클래스 생성 패턴에서 프로토타입이라는 단어를 많이 썼는데 정확히 이게 무엇인지 알아보겠다 자바스크립트는 프로토타입 기반 언어라고 하는 이유는 다른 언어에서 있는 class라는 개념이 자바스크립트에서는 prototype으로 구현 되었기 때문이다 자바스크립트의 모든 함수는 prototype이라는 속성을 가지고 있다

    function Student() {
    	this.legs = 2;
    	this.arms = 2;
    }
    
    let lee = new Student();

위와 같이 선언하면 인스턴스를 만들 수 있지만 몇백개의 학생을 생성해야하면 legs,arms가 각각의 인스턴스마다 생성되어 메모리를 많이 사용하게 된다 이를 아래와 같이 해결 할 수 있다

    function Student() {}
    Student.prototype.legs = 2;
    Student.prototype.arms = 1;
    let lee  = new Student();
    
    console.log(lee.arms); // => 2

이렇게 선언이 되면 어딘가에 존재하는 Student.prototype에서 legs,arms를 가져다 쓸 수 있다 이런 원리를 아래에서 다루겠다

Prototype Link와 Prototype Object

Prototype Object

함수를 정의하면 함수의 생성과 함께 Prototype Object도 같이 생성이 된다 prototype object는 두가지 속성을 가지고 있다

  • constructor : prototypeObject와 같이 생성된 함수를 가리킨다
  • proto : prototype link를 가지고 있다

javascript의 모든 객체는 proto 라는 속성을 가지고 있다 이 속성은 객체가 생성될 때 이 객체를 생성한 함수의 prototype object를 가리킨다

속성을 찾아가는 과정

처음 예시를 든 코드에서 lee 객체는 arms, legs 속성을 가지고 있지 않기 때문에 이 속성을 찾기 위해 위와 같은 체이닝을 이용해 탐색을 한다

lee 에서 탐색을 실행해서 → Student prototype object → Object prototype object(최상위 객체의 prototype object) 까지 찾아본다 만약 존재하지 않으면 undefined를 리턴한다

프로토타입 설명 참조 페이지

profile
데이터에 소외된 계층을 위해 일을 하는 개발자를 꿈꾸는 학생입니다

0개의 댓글