Frontend-dev/HTML-CSS-JS

new 생성자로 객체 만들기

RunningWater 2018. 2. 23. 17:30

new 생성자에 대해 이해하기

자바스크립트에서는 new라는 키워드를 통해 특정 함수로 객체를 만들어 낼 수 있습니다. 쉽게 설명하자면, 붕어빵 틀이 있으면 똑같은 형태의 붕어빵을 계속 찍어낼 수 있습니다. 속에 넣는 재료를 팥이나 생크림, 초콜렛을 넣는다고 하면 맛은 다양하지만 그래도 같은 틀에서 찍어냈으니 똑같은 형태를 가지고 있겠죠. 


new 생성자는 생성자 함수(붕어빵 틀)로 객체 인스턴스(생크림 맛 붕어빵, 초코 맛 붕어빳)를 만듭니다. 

생성자 함수 만들기

function Bread(flavor, price){
  this.flavor = flavor;
  this.price = price;
};
const chocoBread = new Bread("choco", "2200원");
const creamBread = new Bread("cream", "2100원");


예시를 보면서 더 설명해보겠습니다. 생성자 함수라도 일반적인 함수처럼 만드시면 됩니다. 하지만 식별자에 첫글자를 대문자로 해주세요. 보통 자바스크립트에서 식별자를 카멜케이스(소문자로 시작, 띄어쓰기가 필요한 부분마다 대문자)로 많이 나타내지만 생성자 함수라는 것을 다른 사람들이 쉽게 파악하게 하기 위해 생성자 함수는 식별자를 대문자로 시작합니다. 그리고 함수에 flavor와 price라는 매개변수가 있습니다. 함수 바디에서 할당연산자(=) 오른쪽에 있는 값들이 매개변수로 전달된 값이고, 할당연산자 왼쪽에 있는 this.flavor와 this.price는 만들어진 객체의 속성이 됩니다.


this는 만들어질 객체를 가리킨다고 생각하심 됩니다.


new 생성자를 통해서 크림맛과 초코맛 빵을 만들었습니다. 만들어진 객체의 속성을 확인해볼까요?


매개변수로 전달된 값들이 속성 값으로 들어가 있는 것을 확인할 수 있습니다.

상속에 관한 이해

"price of OO bread is OO입니다"라는 메소드를 정의해보겠습니다. 어디에 정의해야할까요? chocoBread와 creamBread라라는 객체에 각각 정의한다면 2번 정의해야합니다.(더 많은 객체를 만들었다면 더 많이 정의해야합니다.) 하지만 그 객체를 만든 원형인 Bread라는 생성자 함수에 정의하면 그 함수를 통해 만들어진 객체가 모두 그 메소드에 접근할 수 있습니다. 이렇게도 생각해보세요. let arr = [1, 3, 2, 4 ,7]이라는 배열이 있고 arr.sort()를 사용하면 [1, 2, 3, 4, 7]로 오름차순으로 정렬시킬 수 있습니다. 우리는 따로 sort()라는 함수를 정의한 적이 없습니다만 사용할 수 있죠. 이것도 다 상속에 의해서 가능한 것입니다. 우리가 배열을 만들면 그 배열은 사실 Array()라는 객체로부터 여러가지를 상속받고 거기에 정의되어 있는 메소드들을 자식이 사용한 것입니다. 

Bread.prototype.isPrice = function(){ console.log(`price of ${this.flavor} bread is ${this.price} 입니다.`); };


위와 같이 정의하면 chocoBread.isPrice()나 creamBread.isPrice()를 이용해서 가격을 볼 수 있습니다. 

__proto__와 prototype의 이해 

프로토타입이란 말 그대로 원형입니다. 


chocoBread객체를 보면 __proto__라는 속성이 있습니다. 이것은 chocoBread가 어디서 상속을 받았는지를 알려줍니다. 함수 Bread로부터 받았다고 나와있죠. 그리고 또 __proto__가 있고 그 옆엔 Object라고 적혀있습니다. 자바스크립트는 모든 것이 객체로부터 시작했습니다. 프로토타입(원형)의 끝은 객체입니다. 객체로부터 만들어졌기 때문에 사실 함수도, 배열도, 기타등등도 모두 객체인 것입니다. prototype은 내 자식들에게 물려줄 것이라고 생각하면 됩니다. 그래서 isPrice()를 정의하고 메소드를 자식이 가져올 수 있었던 것입니다.

undefined를 반환한다는 것의 의미

chocoBread.madeBy라고 치면 undefined를 반환합니다. isPrice()는 객체 인스턴스(chocoBread)에 직접 입력하지 않았지만 사용할 수 있었습니다. 이처럼 속성이나 메소드를 입력하면 맨처음엔 자신에게서 찾고, 자신에게 찾을 수 없으면 부모의 프로토타입에서 찾습니다. 그리고 프로토타입의 끝이 Object에서도 찾을 수 없으면 undefined를 반환합니다. 이처럼 프로토타입을 계속 타고 올라가서 값을 찾는 것을 프로토타입 체인이라고 합니다.


공감은 제작자에게 큰 힘이 됩니다.