객체에는 그 객체가 프로퍼티 타입을 가지고 있는지 확인하는 함수가 있는데 이는 hasOwnProperty( ) 이다.
const user = {
name : 'Mike'
}
console.log(user.name); // 'Mike'
user.hasOwnProperty('name'); // true
user.hasOwnProperty('age'); // false
|
위처럼 hasOwnProperty( )를 통해 user는 name이라는 프로퍼티를 가지고 있지만 age라는 프로퍼티 타입을 가지고 있지 않은 것을 확인할 수 있다.
이 프로토타입을 어떻게 사용하는지 알기 위해서 상속이라는 개념을 사용해서 알아볼 것이다.
아래와 같이 bmw, benz, audi라는 객체가 있다.
bmw는 navigation이 있지만 그 외는 wheel과 drive는 공통으로 가지고 있다.
const bmw = {
color : 'red',
wheels : 2,
navigation: 1,
drive() {
console.log('drive...');
},
};
const benz = {
color : 'white',
wheels : 4,
drive() {
console.log('drive...');
},
};
const audi = {
color : 'yellow',
wheels : 4,
drive() {
console.log('drive...');
},
};
|
그렇다면 이 공통으로 가지고 있는 프로퍼티를 상속받아 사용하는건 어떨까?
car라는 상위 객체를 만들어주고 아래 세 개의 객체가 car 을 상속받도록 해주자.
const car = {
wheels : 2,
drive() {
console.log('drive...');
},
}
const bmw = {
color : 'red',
navigation: 1,
};
const benz = {
color : 'white',
};
const audi = {
color : 'yellow',
};
bmw.__proto__ = car;
benz.__proto__ = car;
audi.__proto__ = car;
// bmw
// {color : 'red', navigation: 1}
|
콘솔에서 bmw 객체를 확인했을 때 color와 navigation 프로퍼티를 가지는 것을 알 수 있다.
bmw.wheels를 해주면 어떨까??
콘솔을 확인해보면 bmw의 wheels가 4로 나오는 것을 알 수 있다.
우선 bmw 객체에서 wheels를 찾는데 없다면 탐색을 멈추고 bmw가 상속받은 __proto__ 타입에서 검색을 해준다.
상속은 계속 이어줄 수 있기 때문에 위와 같이 사용한다면 객체에서 찾고자 하는 특정 프로퍼티를 객체 자체가 가지고 있지 않아도 상속 받은 객체에서 찾아서 그 값들을 반환해 주는 것이다.
객체를 하나 더 만들고 이번에는 bmw 를 상속받아보도록 하자.
const x5 = {
color : 'green',
name : 'x5',
}
x5.__proto__ = bmw;
|
이렇게 bmw를 상속해주었을 때 x5에서 navigation을 찾는다면 어떻게 될까?
찾고자 하는 객체 자체는 navigation을 갖고있지 않으니 __proto__로 상속받은 bmw에서 navigation을 찾고 멈춘다.
x5에서 drive를 찾는다면 bmw의 상위 객체인 car까지 가서 drive를 찾고 멈춘다.
아래와 같은 구도가 형성되는 것이다.
이것을 Prototype Chain 이라고 한다.
__proto__로도 설정할 수 있지만 아래와 같이 사용할 수도 있다.
prototype.을 사용하는 것이다.
const Bmw = function(color) {
this.color = color;
}
Bmw.prototype.wheels = 4;
Bmw.prototype.drive = function() {
console.log("drive..");
};
Bmw.prototype.navigation = 1;
Bmw.prototype.stop = function() {
console.log("STOP!!");
};
const x4 = new Bmw("red");
const z5 = new Bmw("blue");
|
이렇게 하고 생성자 함수를 이용해서 x4와 x5를 만들었을 때 x5.stop( ) 을 해보면 STOP!으로 잘 나오는 것을 볼 수 있다.
생성자 함수가 새로운 객체를 만들어낼 때 그 객체는 생성자 함수의 instance (인스턴스)라고 부른다.
자바스크립트에서는 이 인스턴스를 확인할 수 있는 instanceof 연산자가 있다.
instanceof는 객체와 생성자를 비교할 수 있고,
이는 해당 객체가 그 생성자로부터 생성된 것인지 true,false로 알려준다.
x4 instanceof Bmw; // true
z5 instanceof Bmw; // true
|
또한 이 인스턴스 객체에는 constructor라는 프로퍼티가 존재한다.
이 constructor는 생성자를 가르킨다.
x4.constructor === Bmw; // true
|
x4의 생성자는 Bmw이기 때문에 위의 식은 true가 된다.
Bmw.prototype.~~ 를 조금 더 간략하게 작성하면 아래처럼 사용할 수 있다.
Bmw.prototype = {
wheels: 4,
drive() {
console.log("drive...");
},
navigation: 1,
stop() {
console.log("STOP!");
},
};
|
하지만 위와 같이 사용한다면 constructor가 사라진다.
x4.constructor === Bmw; // false
|
때문에 이를 방지하기 위해서는 객체에 덮어쓰는 것이 아니라 prototype을 사용해서 하나씩 추가하는 것이 좋다.
혹은 객체에 수동으로 constructor를 명시해주어도 된다.
Bmw.prototype = {
constructor: Bmw,
wheels: 4,
drive() {
console.log("drive...");
},
navigation: 1,
stop() {
console.log("STOP!");
},
};
|
이처럼 자바스크립트에서 constuctor는 명확하게 있는 것이 아닌 개발자에 의해 언제든지 수정될 수 있다.
수정하지 못하게 하려면 앞서 배웠던 Closure를 사용하면 된다.
closure에 관련된 글은 아래 링크를 참고하시랏..!!!
https://minbaker.tistory.com/24
[JavaScript] 클로저( Closure ) 이해하기
이번 시간에는 클로저에 대해 알아볼 것이다. 자바스크립트는 어휘적 환경을 갖는다. ( Lexical Environment ) 아래의 코드가 있을 때 어떻게 작동이 되는지 살펴보자, let one; one = 1; function addOne(num) {..
minbaker.tistory.com
const bmw = {
color : 'red',
navigation: 1,
};
const Bmw = function() {
const c = color;
this.getColor = function() {
console.log(c);
}
}
x5.getColor(); // red
|
이렇게 하면 생성자로 만든 객체를 수정할 수 없고 값을 가져올 수만 있다는 것을 알 수 있다.
* 본 포스팅은 코딩앙마님의 자바스크립트 중급 강좌를 기반으로 작성한 글입니다.
'프로그래밍 언어 > JavaScript' 카테고리의 다른 글
[JavaScript] 프로미스( Promise ) (0) | 2022.03.08 |
---|---|
[JavaScript] call, apply, bind (0) | 2022.03.07 |
[JavaScript] 클로저( Closure ) 이해하기 (0) | 2022.03.05 |
[JavaScript] 나머지 매개변수, 전개 구문 (0) | 2022.03.01 |
[JavaScript] 구조 분해 할당 (0) | 2022.02.28 |
댓글