Back Ground

객체 지향 프로그래밍(생성자와 프로토타입) 본문

Javascript

객체 지향 프로그래밍(생성자와 프로토타입)

Back 2018. 10. 4. 17:03






생성자


자바와 동일한 생성자


new를 붙이고 함수처럼 호출

바로 자바스크립트 생성자(constructor) 함수


객체를 생성하는 함수를 생성자 함수라고 부름 

다른 언어에서는 class가 있지만 자바스크립트에서는 없다 

생성자 함수가 그 역할을 대신한다




사람 생성자를 만들면 다음과 같다

1
2
3
4
5
6
7
8
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
  this.sayHello = function() {
    alert(this.name + ' said "hello"');
  }
  this.... // 사람의 속성과 메소드를 더 정의할 수 있습니다.
}
cs

함수를 만들 때처럼 function을 쓰긴 했는데 함수와는 달리 대문자로 시작하게 만든다. (이게 규칙)
생성자를 바탕으로 실제 사람 객체를 만들 수 있다


생성자를 바탕으로 실제 사람 객체를 만들 수 있다.

new라는 키워드를 사용해서 호출

 new 생성자(인자);이렇게 하면 된다.


1
2
3
4
var zero = new Person('Zero''m'); // Person {name: 'Zero', gender: 'm'}
var hero = new Person('Hero''f'); // Person {name: 'Hero', gender: 'f'}
zero.sayHello(); // 'Zero said "hello"'
hero.sayHello(); // 'Hero said "hello"'
cs



하나의 Person 생성자를 바탕으로 zero와 hero 두 사람 객체를 만들었다.

그리고 이 객체들은 공통적으로 sayHello라는 메소드를 갖고 있다.





1
2
3
4
5
6
7
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
  this.sayHello = function() {
    alert(this.name + ' said "hello"');
  }
}
cs


Person 옆에 (name, gender)는 처음 만들 때 매개변수를 받는 부분임을 알 수 있다.

그렇게 받은 매개변수들을 this.namethis.gender에 저장


 this는 바로 생성자 함수 자신을 가리킨다


이렇게 this에 저장된 것들은 new를 통해 객체를 만들 때 그 객체에 적용





프로토 타입


1
2
3
4
5
6
7
function Person(name, gender) {
  this.name = name;
  this.gender = gender;
}
Person.prototype.sayHello = function() {
  alert(this.name + ' said "hello"');
};
cs


this.sayHello 대신에 Person.prototype에 sayHello를 넣었다.

 prototype 객체는 사전 그대로 원형을 뜻함



같은 생성자로부터 만들어진 객체들은 모두 이 원형 객체를 공유

따라서 Person의 prototype 객체에 sayHello라는 메소드를 넣으면 Person 생성자로 만든 모든 객체는 이 메소드 사용이 가능





그런데 this.sayHello보다 prototype에 Person.prototype.sayHello로 넣는 게 더 효율적


prototype은 모든 객체가 공유하고 있어서 한 번만 만들어지지만

this에 넣은 것은 객체 하나를 만들 때마다 메소드도 하나씩 만들어지기 때문에 불필요한 메모리 낭비가 발생


아예 메소드뿐만 아니라 속성까지 다 prototype에 넣기도 함





prototype과 __proto__


1
new Person('Nero''m'); // Person {name: "Nero", gender: "m", __proto__: Object}
cs

Nero라는 새 사람 객체를 만들었더니 그 안에 처음보는 __proto__라는 객체가 있다.


constructor과 우리가 추가한 sayHello 그리고 또다시 __proto__가 있다.

1
2
3
4
5
{
  constructor: function Person(name, gender),
  sayHello: function() {},
  __proto__: Object
}
cs




undefined

__proto__가 바로 실제 객체를 만들 때 생성자의 prototype이 참조된 모습



생성자의 prototype을 참조하기 때문에 __proto__와 prototype은 같다

아까 Person.prototype.sayHello를 했던 것이 들어있는데

추가로 constructor(생성자)에 대한 정보까지 들어있다.


__proto__ 안에 __proto는 객체상속때 쓰는것 추후에 알아 사용해보자.



정리하면

  • constructor는 생성자 함수 그 자체를 가리킴
  • prototype은 생성자 함수에 정의한 모든 객체가 공유할 원형
  • __proto__는 생성자 함수를 new로 호출할 때, 정의해두었던 prototype을 참조한 객체
  • prototype은 생성자 함수에 사용자가 직접 넣는 거고, __proto__는 new를 호출할 때 prototype을 참조하여 자동으로 만들어짐
  • 생성자에는 prototype, 생성자로부터 만들어진 객체에는 __proto__
  • 따라서 사용자는 prototype만 신경쓰면 된다. __proto__는 prototype이 제대로 구현되었는지 확인용으로 사용한다.






prototype, __proto__와 constructor의 관계

Person.prototype.constructor === Person;
prototype과 constructor는 부모자식 관계라고 생각하면 된다.


또한 Person.prototype === (Person생성자로 만들어진 객체).__proto__; 이기 때문에

 (Person생성자로 만들어진 객체).__proto__.constructor === Person; 도 성립한다.





상속의 필요성

위와 같이 생성자 함수를 만들고, new 키워드를 통해 객체도 만들었다

Person 생성자 외에도 Vehicle이나 Machine 같은 생성자를 만들 수도 있을것이다


1
2
3
4
5
6
7
function Vehicle(name, speed) {
  this.name = name;
  this.speed = speed;
}
Vehicle.prototype.drive = function () {
  console.log(this.name + ' runs at ' + this.speed)
};
cs



이렇게 Vehicle 생성자 만들고 drive 메소드로 달릴 수 있는데

 

근데 drive 메소드 하나밖에 없으니 좀 그러니

 boost라는 메소드를 만들어서 최고 속도로 달릴 수 있는 기능을 추가하면 괜찮을 거 같아서


Vehicle.prototype.boost = function () {...} 이렇게 추가하자니 

한 가지가 걸린다.


 Vehicle 안에는 트럭, SUV, 스포츠카, 세단 등 많은데 트럭이 boost하는 건 좀 이상하지 않나?



이럴 때 상속이 필요 

상속은 외국에서 확장(extend)이라고도 표현 


즉 부모 생성자의 기능을 물려받는 동시에 새로운 기능을 추가할 수도 있다.






출처 : https://www.zerocho.com/category/JavaScript/post/573c2acf91575c17008ad2fc

'Javascript' 카테고리의 다른 글

고차 함수(Currying 커링)  (0) 2018.11.28
Object 객체  (0) 2018.10.07
Date, RegExp 객체  (0) 2018.10.04
JavaScript 핵심요약  (0) 2017.12.22
javascript 파일 압축 및 복원하기 (***.min.js 파일 만들기)  (0) 2017.05.30
Comments