자바스크립트 객체 다시 이해하기
var healthObj = {
name : "crong",
lastTime : "PM10:12",
showHealth : function() {
console.log(this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요");
}
}
healthObj.showHealth();
자바스크립트의 프로토타입 특성 이해
- 자바스크립트도 객체지향언어임.
- 그런데, 자바스크립트에는 클래스라는 개념이 없음
- 대신 프로토타입(Prototype)이라는 것이 존재함.
자바스크립트가 프로토타입 기반 언어
라고 불리는 이유 - 클래스가 없으니 기본적으로
상속기능도 없음
. 그래서 보통 프로토타입을 기반으로 상속을 흉내내도록 구현해 사용 - 참고로 최근의 ECMA6 표준에서는 Class 문법이 추가됨. 하지만 문법이 추가되었다는 것이지, 자바스크립트가 클래스 기반으로 바뀌었다는 것은 아님
- 대신 프로토타입(Prototype)이라는 것이 존재함.
객체 동적 생성 - 비슷한 객체를 중복해서 만들고 싶을 때
생성자 함수
를 이용한다!
function Health(name, lastTime) {
this.name = name;
this.lastTime = lastTime;
this.showHealth = function(){
return this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요"
}
}
- 아래와 같이 객체를 만들수 있을까?
- 결과는 undefined
var obj = Health("crong", "AM 10:10");
객체 동적 생성방법
new 키워드
이용!!Health 함수
는 new 키워드로 불리면서, 객체를생성하는 함수 역할
(객체 생성자라고 불림)
var obj1 = new Health("crong", "AM 10:10")
var obj2 = new Health("호눅스", "AM 12:00")
console.log(obj1.showHealth() === obj1.showHealth()) // false
-
obj1.showHealth() 함수와 obj2.showHealth() 함수는 각각 가리키고 있는 메모리 위치가 다르다!
-
이 때, 생성자들이
프로토타입
이라는것을 가지고 있도록 할 수 있음- 프로토타입 안을 들여다보면 같은 지점의 메소드들을 바라보고 있음
- obj1이 메모리공간에 있는 위치와 obj2가 메모리공간에 있는 위치가 같게 위치시킬 수 있음!
function Health(name, lastTime) {
this.name = name;
this.lastTime = lastTime;
}
Health.prototype.showHealth = function(){
return this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요"
}
var obj1 = new Health("crong", "AM 10:10")
var obj2 = new Health("호눅스", "AM 12:00")
console.log(obj1.showHealth === obj2.showHealth) // true
- obj1.showHealth 함수는 obj1 인스턴스의 프로토타입(Health) 안에 들어있는 것을 가리키고 obj2.showHealth 함수 역시 obj2 인스턴스의 프로토타입(Health) 안에 들어있는 것을 가리킴
- 두 인스턴스의
프로토타입은 Health 함수내에 존재
하며,같은 메모리 공간을 가리키므로
마지막 console이 true를 반환함
- 두 인스턴스의
- 다른 예제
function Person() {}
Person.prototype.eyes = 2;
Person.prototype.nose = 1;
var kim = new Person();
var park = new Person():
console.log(kim.eyes); // => 2
- kim에는 eyes라는 속성이 없는데도 kim.eyes를 실행하면 2라는 값을 참조
- kim이 가지고 있는 딱 하나의 속성 __proto__가 그것을 가능하게 해주는 열쇠
prototype 속성은 함수만 가지고 있던 것
과는 달리__proto__속성은 모든 객체가 빠짐없이 가지고 있는 속성
- __proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킴
- kim객체는 Person함수로부터 생성되었으니 Person 함수의 Prototype Object를 가리키고 있는 것
생각해보기
-
prototype과 new 키워드를 사용해서 구현할 수 있는 객체지향 자바스크립 코드가 어떤 형태인지?
-
Prototype Link :
__proto__
라는 속성이 있습니다. 앞선 예제에서 obj1, obj2를 이용해서 obj2.proto 와 같은 식으로 접근해서 결과를 확인해보세요. 직접 쓸 일은 없지만, 내부 prototype 정보를 들여다볼 수 있습니다.
function Health(name, lastTime) {
this.name = name;
this.lastTime = lastTime;
}
Health.prototype.showHealth = function(){
return this.name + "님, 오늘은 " + this.lastTime + "에 운동을 하셨네요"
}
var obj1 = new Health("crong", "AM 10:10")
var obj2 = new Health("호눅스", "AM 12:00")
console.log(obj2.__proto__) // {showHealth: ƒ, constructor: ƒ}
- 다른 예제
- __proto__를 사용하여 다른 객체 상속 받기
- 아래의 예제에서 subObj가 superObj 객체를 상속받는다 (2번 결과)
- 즉, 위의 prototype과 같은 효과를 나타낸다
- subObj 객체로 superVal 를 바꿔도 반영이 되지 않는다 (3번 결과)
var superObj = {superVal:'super'}
var subObj = {subVal:'sub'}
subObj.__proto__ = superObj;
console.log(subObj.subVal); // 1. sub
console.log(subObj.superVal); // 2. super
subObj.superVal = 'sub';
console.log('superObj.superVal =>', superObj.superVal); // 3. super
- Object.create 를 사용해서도 클래스와 같은 코드를 만들 수 있습니다. ES6에서는 Class라는 키워드가 존재합니다. 어떻게 클래스를 만들고 메서드를 추가할 수 있는지 예제를 찾아서 확인해보세요. 많은 framework들이 이런 패턴으로 컴포넌트를 만들고 있습니다. 그런데 ES6 Class도 결국은 prototype을 활용해서 클래스구조를 생성한답니다. 따라서 prototype에 대한 이해는 자바스크립트를 이해하는데 꼭 알아둬야 할 개념입니다.
class Food {
constructor(name) {
this.name = name;
this.brands = [];
}
addBrand(brand) {
this.brands.push(brand);
}
print() {
console.log(`${this.name}을 파는 음식점들`);
console.log(`[ ${this.brands.join(",")} ]`);
}
}
class Chicken extends Food {
constructor() {
super("치킨");
}
}
class Pizza extends Food {
constructor() {
super("피자");
}
}
const pizza = new Pizza();
pizza.addBrand("피자헛");
pizza.addBrand("도미노피자");
pizza.addBrand("오구쌀피자");
const chicken = new Chicken();
chicken.addBrand("굽네치킨");
chicken.addBrand("교촌치킨");
chicken.addBrand("왕천파닭");
pizza.print();
chicken.print();
// 피자을 파는 음식점들
// [ 피자헛,도미노피자,오구쌀피자 ]
// 치킨을 파는 음식점들
// [ 굽네치킨,교촌치킨,왕천파닭 ]
관련 링크
-
https://opentutorials.org/module/4047/24626
-
https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
-
https://blog.naver.com/nebi25/221749567662
-
https://medium.com/@han7096/javascript-core-3-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-prototype-c2da4c24820e