TIL prototype

백광호·2021년 1월 15일
0

TIL

목록 보기
36/55

코드스테이츠 40일차

어제에 이어 객체 지향 프로그래밍에대한 포스팅의 연장이다.
클래스라는 문법이 ES6에서 추가되었기 때문에
과거에 이용했었던 방법을 알면 클래스의 작동 방식을
어느정도 알 수 있다.

오늘은 그에대한 포스팅이다.

새로 배운 것들

ES6 이전 객체 지향 프로그래밍

클래스가 없었을때에는 어떻게 객체 지향 프로그래밍을 했을까?

var Car = function(position) {
  var someInstance = {}; // 함수를 실행했을 때 담아줄 객체
  someInstance.position = position; // position값의 초기화 부분
  someInstance.move = function() { // 메소드 추가
    this.position += 1;
// this.position === someInstance.position
  }
  return someInstance; // 함수 실행 결과 출력
};

var car1 = Car(5) // position 초기값은 5
car1.move() // move 메소드 실행
console.log(car1.position)  //output 6

이런식으로 만들면 함수를 재사용해서 클래스처럼 쓸 수 있다.
여기에 또다른 자동차를 만드려면 var car2 = Car()을 쓰면 될 것이다.

이렇게보면 클래스를 만드는것과 똑같이 보인다.

위 방식 말고도 다른 방식이 또 있는데
바로 Object.create를 이용하는 방법이다.

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);
car1.move()
console.log(car1.position) // output 6

여기서 Object.create의 역활은 무엇일까?
MDN에서 살펴보면 지정된 프로토타입 객체 및 속성을 갖는
새 객체를 만든다고 되어있다.

위의 예제에서 두번째 줄에 // 함수를 실행했을 때 담아줄 객체
라고 주석을 달아놓았는데 Object.create가 그 역활을 하는것이다.
여기서 또하나 의문이 드는데 프로토타입이 무엇이냐는 것이다.

이제 여기서 오늘의 주제인 prototype에 대해 알아보자

ES6 이전에 객체 지향 프로그래밍에서 클래스를 만드는 방법중
그나마 간결한 방법이 있다.

var Car = function(position) {
  this.position = position;
};

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

var car1 = new Car(5);
car1.move()
console.log(car1.position) // output 6

이렇게 프로토타입을 이용하면 더 간결하게 만들 수 있다.
이렇게 선언한 함수로 객체를 만들때에는 new를 붙여줘야한다.
이는 현제 사용되는 클래스로 선언한 객체를 만들때에도 동일하다.

이상태에서 부모의 객체를 상속받는 방법은 아래와 같다.

var Car = function(position) {
  this.position = position;
};

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

var Minicar = function() {
  Car.call(this, position) // Car.apply(this, arguments)
}

var car1 = new Car(5);
car1.move()
console.log(car1.position) // output 6

이제 prototype에 대해 자세히 살펴보자

prototype

prototype은 쉽게 생각해서 상위객체라고 보면 된다.

function Human(name) {
  this.name = name;
}

let steve = new Human('steve')
steve.__proto__

위와 같이 입력하면

이렇게 나오는걸 볼 수 있는데 여기서 생성자인 constructor을 누르면
steveHuman의 자손으로 들어가 있는걸 알 수 있다.

그렇기 때문에

steve.__proto__ === Human.prototype
// output true

이렇게 나온다
여기서 한층 더 들어가게 되면

steve.__proto__.__proto__ === Object.prototype
//  output true

Object와 동일하다고 볼 수 있는데
이렇게 연결되어있는 관계를 프로토타입 체인이라고 한다.
프로토타입 체인으로 연결되어있기 때문에
steve에는 선언하지 않았던 toStiring()이 사용이 가능하다.

steve.toString()
// output "[object Object]"

toString() 메소드는 Object에 내장되어있는 메소드이다.

정리를 해보면
Human은 steve의 생성자 constructor이며
__proto__는 객체에서 접근하는 인스턴스 확인 방법이고
prototypeconstructor함수에서 접근하는 인스턴스 확인 방법이다.
때문에 Object 가 가지고 있는 속성은 Human도 가지고 있고
steveObjectHuman의 속성을 모두 가지고 있는 형태로 보여진다.

그래서 억지로 stevetoString()이 사용이 가능한 것이다.

프로토타입을 이용해 유사배열을 만드는 것도 가능하다.

let MyArray = function() {}

MyArray.prototype = Array.prototype;

let myarr = new MyArray();
myarr.push(1);
console.log(myarr)
// output MyArray [1]

prototype이 어떤방식으로 작동되는지 알아보았는데
조금은 복잡할수도 있겠지만 쉽게 생각해보면
그렇게 어려운것도 아닌것 같다.

이 글은 어제 썼던 객체 지향 프로그래밍 글과
함께 보면 좋을것 같아 링크로 남겨두었다.

profile
안녕하세요

0개의 댓글