일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- nest.js circular Dependency
- Testing-library/react
- react testing library 비동기 테스트 사용법
- TDD방식으로 리액트 테스팅
- nest.js forwardRef
- react 테스트
- 비동기 테스트
- 개발
- mock api 사용법
- React 테스트코드
- react jest
- 첫코딩
- javascript 테스트
- React Testing Library
- react
- nest.js 순환 참조
- 첫 코딩
- 리액트 테스트 코드
- TodoList 테스트 코드
- CSS
- FlatList 무한 스크롤
- react native 무한스크롤
- nest.js 순환 종속성
- JavaScript
- ScrollView 무한 스크롤
- 프로젝트 배포하기
- mock api를 이용한 react 테스트
- HTML
- 리액트 테스트
- jest
- Today
- Total
성장을 위한 기록
중급 기본 정리 (with 앙마코딩) 상속과 Prototype 본문
이 글은 인프런에서 앙마코딩님의 무료 강좌를 학습한 내용입니다. (자바스크립트 중급 강좌)
문제 시 바로 삭제하겠습니다.
출처 [무료] 자바스크립트 중급 강좌 대시보드 - 인프런 | 강의 (inflearn.com)
상속과 Prototype
객체에서 자신이 프로퍼티를 가지고 있는지 확인 하는 프로퍼티가 있다. 이는 hasOwnProperty
이다.
const my = {
name : 'Btae',
};
// my.name > 'Btae'
//my.hasOwnProperty('name') > true
//my.hasOwnProperty('age') > false
이렇게 객체에 있다면 true, 없다면 false를 반환한다.
하지만 우리는이 hasOwnProperty
프로퍼티를 만든적이 없다. 그렇다면 어디에 존재하나?
바로 __proto__
에 존재한다. 객체 프로퍼티를 찾을 때 먼저 객체 내부를 찾고 없으면 __proto__
안을 찾게 된다.
그렇다면 만약 객체 프로퍼티에 hasOwnProperty
가 있다면?
const my = {
name : 'Btae',
hasOwnProperty : function(){
console.log('hello,');
};
// my.name > 'Btae'
//my.hasOwnProperty('name') > 'hello,'
//my.hasOwnProperty('age') > 'hello,'
기존에 사용하던 기능을 잃고 하나의 키값으로 프로퍼티를 반환하게 된다.
이는 위에 언급했듯 찾는 과정에서 객체 내부를 먼저 확인하고 __proto__
를 확인하는데 객체 내부에 키값으로 존재하기 때문에, 먼저 반환하고 더 이상 찾지 않는 것이다.
나는 이 __proto__
를 상속으로 이해했다.
예를 들어보자
const k3 = {
name: 'k3',
color : 'red',
wheels: 4,
drive() {
console.log('drive');
},
};
const k5 = {
name : 'k5',
color : 'black',
wheels: 4,
drive() {
console.log('drive');
},
};
const k9 = {
name:'k9',
color:'white',
wheels: 4,
drive() {
console.log('drive');
},
};
이렇게 자동차 모델에 정보를 갖는 객체가 있는데, 공통되는 부분이 많아 이를 효율적으로 작성하고 싶을 때 상속의 개념을 이용할 수 있다.
간단하게 변경을 해보면
const car = {
wheels: 4,
drive() {
console.log('drive');
},
};
const k3 = {
name: 'k3',
color : 'red',
};
const k5 = {
name : 'k5',
color : 'black',
};
const k9 = {
name:'k9',
color:'white',
};
k3.__proto__ = car;
k5.__proto__ = car;
k9.__proto__ = car;
이렇게 공통되는 부분을 따로 car라는 객체로 만들어 이 객체를 각각의 객체에 상속을 하는 것이다.
따라서 k3, k5, k9은 .__proto__
를 통해 각각 car객체를 상속받은 것이다.
위 코드를 콘솔창에서 확인을 해보면
k3 > {name:'k3', color: 'red'}
k3.name = 'k3'
k3.wheels = 4
k3.hasOwnProperty('age') > false
k3.hasOwnProperty('wheels') > false
이 예시를 살펴보자. 우선 k3객체는 변하지 않았다 그 이유는 상속 받은 객체는 앞서 언급함 __proto__
안에 존재하기 때문이다.
그래서 객체 내에는 없지만, k3.wheels
를 확인해보면 상속 받은 값 4가 반환된다.
그런데 객체 내에 프로퍼티가 있는지 찾는 hasOwnProperty
를 사용하면 false가 나타난다.
이유는 hasOwnProperty
는 객체 내에서만 확인을 하고 __proto__
는 확인하지 않기 때문이다.
상속은 계속 할 수 있다.
/*앞선 예제 코트 ....
... k3..__proto__ = car;*/
const k3_hev = {
moter : 'hev',
};
k3_hev.__proto__ = k3;
위 코드처럼 상속 받았던 k3를 다른 객체에 상속할 수 있다.
단, 상속된 객체는 한 객체에 같이 있는 것이 아니다. 쉽게 말해서 우리는 상속된 객체를 콘솔창에서 __proto__
으로 확인 할 수 있었다. 이 __proto__
가 중첩되어 쌓인다고 생각하면 된다.
이 개념이 필요한 이유는 객체에 프로퍼티를 찾는 과정이 있기 때문이다. 앞서 말했듯 객체 내에서 먼저 찾고 없으면 상속된 __proto__
에서 찾게 된다. 그리고 나중에 상속된 객체가 최상의 상속 객체가 된다.
위 예제를 보며 설명을 해보면 k3_hev.wheels
를 찾는다 가정을 해보자. 우선 k3_hev 자체 객체 내에서 찾게된다. 이 객체에 없다면 최상의 상속객체인 k3에서 찾게된다. k3에도 없기 때문에 그 다음 상속된 객체인 car에서 찾게되고 car에서 찾은 후에는 찾는 과정을 멈추고 4라고 반환하게 된다. 이런 과정을 Prototype Chain이라고 한다.
상속에 따라 메서드 사용이 달라질 수 있다.
위 예제를 가지고 왔다고 생각을 하고
for( p in k3_hev){ // for in을 통해 반복하여 객체 반환
console.log(p);
};
/*moter
name
color
wheels
drive
*/
k3_hev > {moter: 'hev'}
Object.keys(k3_hev); > ['motor']
Object.values(k3_hev); > ['hev']
위 예제를 살펴보면 for in
을 통해 객체를 순회했을 때에는 상속된 객체까지 순회하여 모든 키값을 반환했다.
반대로 keys,values
를 통해 반환했을 때에는 k3_hev가 가지고 있는 객체 내에서만 반환했다.
이렇게 상황에 따라 사용할 방법이 달라질 수 있다.
만약 for in
을 통해 반환하고 싶다면 hasOwnProperty
를 사용하자.
앞서 언급한대로 hasOwnProperty
는 객체 내에서만 탐색하기 때문에
/*for(p in k3_hev}{
console.log(p);
};
*/
for(p in k3_hev){
if(k3_hev.hasOwnProperty(p)){
console.log(p);
};
이렇게 변경한다면 객체 내에 있는 값만 true를 반환하기 때문에 상속된 값이 반환되는걸 막을 수 있다.
생성자 함수를 이용한 상속
생성자 함수를 통해 만든 객체에도 당연히 상속을 할 수 있다.
const car = {
wheels:4,
drive(){
console.log('drive');
},};
const Kia = function(color) {
this.color = color;
};
const k5 = new Kia('red');
const k3 = new Kia('white');
k5.__proto__ = car;
k3.__proto__ = car;
앞선 예제는 k3,k5객체를 직접 정의했다면 이번에는 생성자 함수를 통해 객체를 만들었다.
그런데 개발자들은 불편한 걸 그냥 보고있지 않는다.
위 코드에서 생성자 함수를 통해 만든 객체에 계속해서 상속을 해야하기 때문에 많아지면 더 불편하게 다가온다.
그래서 생성자 함수에 상속을 할 수 있는 기능이 있다.
const Kia = function(color) {
this.color = color;
};
Kia.prototype.wheels = 4;
Kia.prototype.drive = function () {
console.log('drive');
};
const k5 = new Kia('red');
const k3 = new Kia('white');
같은 기능을 하는 코드를 이렇게 간단하게 작성할 수 있다.
여기서 사용된 prototype
은 생성자 함수 객체에 . 이후에 오는 프로퍼티를 상속한다. 즉 기존 코드에 k5.__proto__ = car;
부분을 적은 것이라 생각하면 된다.
생성자 함수를 통해 만들어진 객체는 생성자 함수의 인스턴스(instance)라고 불린다
그리고 이를 확인 할 수 있는 instanceof 연산자가 존재하며 값은 불린 값을 반환한다.
위 예제를 예로 들어k5 instanceof Kia
는 true를 반환한다.
생성자 함수의 인스턴스 객체에는 constructor이라는 프로퍼티가 존재한다.
k5.constructor === Kia > ture
객체.constructor은 그 객체에 생성자 함수를 뜻한다.
다시 위에 예제로 돌아가서 우리는 위 코드를 더 간단하게 줄 일 수 있다.
const Kia = function(color) {
this.color = color;
};
Kia.prototype = {
//constructor : Kia,
wheels: 4,
drive(){
console.log('drive');
},
};
const k5 = new Kia('red');
const k3 = new Kia('white');
이와 같은 방법으로 생성자 함수에 상속을 객체로 만들어 더 간단하게 작성 할 수 있다. ( 이 방법은 상속될 프로퍼티가 많으면 많을 수록 도움이 될 것이다.)
다만 이 방법을 사용하면 k5.constructor === Kia > false 를 반환한다.
그래서 우리는 이 방법을 사용안하거나, 주석처리가 된 부분처럼 직접 입력해 사용할 수 있다.
'FE (Front End) (구) > javascript' 카테고리의 다른 글
중급 기본 정리 (with 앙마코딩) Promise 프로미스 async, await (0) | 2022.03.19 |
---|---|
중급 기본 정리 (with 앙마코딩) Class 클래스 (0) | 2022.03.18 |
중급 기본 정리 (with 앙마코딩) call, apply, bind (0) | 2022.03.16 |
중급 기본 정리 (with 앙마코딩) setTimeout / setInterval (0) | 2022.03.16 |
자바스크립트 중급(with 앙마코딩) 나머지 매개변수, 전개 구문 (0) | 2022.03.15 |