JavaScript_ OOP 상속 패턴

Adela·2020년 11월 23일
0

JavaScript

목록 보기
14/17
post-thumbnail

상속 패턴

JavaScript에는 아래와 같이 네가지 instantiation pattern이 있다.
1. Functional
2. Functional-shared
3. Prototypal
4. Pseudoclassical

Functional instantiation 방식

let Car = function(){  // 1.
  let someInstance = {}  // 2.
  someInstance.position = 0;  // 3.
  someInstance.move = function(){
    this.position += 1;  //4.
  }
  
  return someInstance;  // blueprint객체를 함수의 결과로
}

복제 될 instance들이 공통적으로 갖는 properties/Attribute & Methods/Behaviours 정의해주는 과정
PSEUDOCODE
1. 먼저 Car라는 함수를 만든다.
2. Car함수를 실행했을 때 찍어낼 객체를 선언한다.
3. someInstance의 position을 0으로 초기화해주어 찍어낸 객체들의 초기값이 항상 0이 되도록한다. 새 차니까
4. move라는 능력method를 추가해준다. method 실행 시 position값이 1만큼 증가할 것이다.

let car1 = Car();
let car2 = Car();
car1.move();  // 실행될 때마다 car1; 해보면 position이 1씩 늘어나있다. 

let car1 = Car(5); // 초기 위치를 지정해줄 수도 있다.

Functional Shared 방식

let Car = function (position){  // 1.
  let someInstance = {
    position : position,  // 2.
  };
  return someInstance;
};
// 3.
let someMethods = {};
someMethods.move = function(){
  this.position += 1;
};
// 4.
let extend = function (to, from){
  for(let key in from){
    to[key] = from[key];
  }
}

extend(someInstance, someMethods);

PSEUDOCODE
1. 먼저 Car라는 함수를 만든다.
2. 바로 position을 property로 넣어준 채로 객체를 만든다.
3. 메소드를 담아줄 객체를 생성한다. 모든 메소드는 이 객체에 넣을 것이다.
4. someInstance와 someMethods를 합치는 extend함수를 만들어서 Car함수 내부에서 합친다.

완성된 코드

let extend = function (to, from){  // 4.
  for(let key in from){
    to[key] = from[key];
  }
}

let someMethods = {};  // 3.
someMethods.move = function(){
  this.position += 1;
};

let Car = function (position){  // 1.
  let someInstance = {
    position : position,  // 2.
  };
  extend(someInstance, someMethods);  // 4.
  return someInstance;
};

왜 굳이 번거롭게 Functional Shared 방식을 사용할까?

이전의 Functional instantiation 함수방식은 instance생성 때마다 모든 메소드를 someInstance에게 할당하므로, 각각의 instance들이 메소드 수만큼 메모리를 더 차지한다.
근데 이 Functional Shared방식을 사용하면,
someMethods라는 객체에 있는 메소드들의 메모리 주소만 참조하기 때문에 메모리 효율이 좋아진다.

Functional instantiation
3개의 instances, 6칸의 메모리

car 1's positionsomeMethods >> move
car 2's positionsomeMethods >> move
car 3's positionsomeMethods >> move

Functional Shared
3개의 instances, 4칸의 메모리

car 1's position
car 2's position
car 3's position

someMethods >> move

Functional Shared방식을 사용하면 메모리 사용이 효율적이다.

Prototypal 방식

functional Shared방식과 비슷한 코드를 작성한다.

var someMethods = {};
someMethods.move = function(){
  this.position ++;
};

var Car = function(position){
  var someInstance = {};  //여기를 바꿀 것
  someInstance.position = position;
  return someInstance;
};
var someMethods = {};
someMethods.move = function(){
  this.position ++;
};

var Car = function(position){
  var someInstance = Object.create(someMethods); //여기만 바꿨다.
  someInstance.position = position;
  return someInstance;
};

var car1 = Car(5);
var car2 = Car(10);

Object.create()은 특정 객체를 prototype으로 하는 객체 및 속성을 갖는 새 객체를 생성해주는 함수

Object.create(proto)

  • proto: 새로 만든 객체의 프로토타입이어야 할 객체.
  • 반환값: 지정된 프로토타입 개체와 속성을 갖는 새로운 개체.

Pseudoclassical 방식 - 가장 많이 쓰는 방식

  1. 함수를 작성한다.
  2. this 키워드로 속성을 정의한다.
  3. 메소드를 prototype에 정의한다.
  4. new 키워드로 객체의 인스턴스 객체를 생성한다.
var Car = function (position){
  this.position = position;  // 1. 2.
}

Car.prototype.move = function(){
  this.position++;  // 3.
}

var car1 = new Car(5); 
var car2 = new Car(10);  // 4.
console.log(car2);  // Car {position: 10}
car2.move();
car2.move();
car2.move();
console.log(car2);  // Car {position: 13}
console.log(car2.position);  // 13

this

함수가 실행될 때, 해당 scope마다 생성되는 고유한 실행컨텍스트(execution context)
new 키워드로 instance를 생성했을 때에는 해당 instance가 this의 값이 된다.


function Car(brand, name, color) { 
  this.brand = brand;  // 이 예제에서 this는 avante
  this.name = name;
  this.color = color;
}

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

let avante = new Car('hyundai', 'Avante', 'black')
avante.color;    // 'black'
avante.drive();  // Avante가 운전을 시작합니다

배열과 객체지향프로그래밍의 유사성

배열을 정의하는 것은 Array의 instance를 만들어내는 것과 동일하다.

let avante = new Car ('hyundai', 'avante', 'blue');
avante.color;  // 'blue'
avante.drive;  // avante출발!!

let arr = ['code', 'states', 'pre'];
// 따라서 let arr = new Array('code', 'states', 'pre'); 도 동일함
arr.length;  // 3
arr.push('course');   // 새 element추가
profile
👩🏼‍💻 SWE (FE)

0개의 댓글