일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- DynamoDB
- Await
- AWS
- 구조분해 할당
- 옵셔널 체이닝
- Proxy Resource
- Service
- grafana
- JavaScript
- Site-to-Site VPN
- On-Premise
- null 병합 연산자
- 단축 평가
- vgw
- CloudFormation
- api gateway
- 온프레미스
- 자바스크립트
- Custom Resource
- docker
- cognito
- optional chaining
- Kubernetes
- elasticsearch
- 비구조화 할당
- docker swarm
- VPC
- prometheus
- transit gateway
- Endpoints
- Today
- Total
만자의 개발일지
[JavaScript] 생성자와 프로토타입 본문
자바스크립트는 함수형 언어입니다.
자바같은 객체지향 언어에서 생성자는 클래스안에 속하지만, 자바스크립트에서는 객체를 만드는 주체가 함수가 됩니다.
물론 자바스크립트에서도 클래스 문법을 사용할 수 있지만 자바스크립트를 자바스크립트답게 사용하기위해서는 함수사용을 지양하는게 좋습니다.
생성자
생성자는 객체를 생성하기 위한 함수입니다.
예제를 통해 살펴보도록 하겠습니다.
다음과 같이 생성자를 구현하였습니다. 생성자 매게변수로 학년과 이름을 입력받고 그 정보를 introduce() 함수로 출력할 수 있습니다.
생성자는 다른 함수들과달리 대문자로 시작합니다. 자바에서 class 표기를 대문자로 시작하는 것처럼 생성자 역시 객체를 생성하기 위한 함수이기 때문에 대문자로 시작하는 것이 좋습니다.
function Student(grade, name) {
this.grade = grade
this.name = name
this.introduce = function() {
console.log('학년: ' + this.grade + ' 이름: ' + this.name)
}
}
자바스크립트에서 생성자는 new 연산자를 통해 호출할 수 있습니다. new 연산자를 사용하지 않으면 생성자를 반환할 수 없기 때문에 undefined가 뜨게 됩니다.
var gildong = new Student(3, '홍길동')
var cheolsoo = Student(1, '김철수')
console.log(gildong)
console.log(cheolsoo)
Student { grade: 3, name: '홍길동', introduce: [Function (anonymous)] }
undefined
여기서 잠깐 new 연산자의 원리에 대해 짚고 넘어가도록 하겠습니다.
new 연산자를 사용하면 내부적으로 다음과 같이 동작하게 됩니다.
- 빈 객체를 생성한다.
- 새로 생성된 빈 객체는 생성자의 프로토타입을 상속받는다.
- this를 새로 생성된 객체에 바인드 시킨다.
- 생성자에 명시적으로 다른 객체를 리턴하지 않는 경우, this로 바인드된 이 객체가 반환된다. (일반적으로 생성자는 값을 리턴하지 않는다.)
프로토타입
프로토타입은 말그대로 원형을 의미합니다.
자바스크립트에서는 객체를 생성했을 때 그 객체안에 prototype이라는 객체가 자동으로 생성되고 그 프로토타입안에 생성자를 가르키는 constuctor라는 객체가 자동으로 생성되어 서로 참조할 수 있게 됩니다.
이러한 프로토타입은 생성자로 생성된 각각의 객체가 프로퍼티나 함수를 를 공유하기 위해 사용됩니다.
예제를 통해 살펴봅시다.
위의 코드와 똑같이 동작하긴 하지만 이번에는 this.introduce가 아닌 Student.prototype.introduce로 선언해 주었습니다.
this로 선언할 경우 생성자를 호출 할때마다 프로퍼티와 메소드도 하나씩 만들어지기 때문에 프로토타입을 사용하면 프로퍼티나 메소드가 한 번만 만들어져 해당 메모리를 공유할 수 있게되고 불필요한 메모리 낭비를 줄일 수 있습니다.
function Student(grade, name) {
this.grade = grade
this.name = name
}
Student.prototype.introduce = function() {
console.log('학년: ' + this.grade + ' 이름: ' + this.name)
}
var gildong = new Student(3, '홍길동')
var cheolsoo = new Student(1, '김철수')
gildong.introduce()
cheolsoo.introduce()
학년: 3 이름: 홍길동
학년: 1 이름: 김철수
생성자와 프로토타입이 서로 참조한다고 했습니다. 실제로 서로 참조하고 있기 때문에 다음과 같은 경우도 만족할 수 있습니다. __proto__는 실제 객체를 만들 때 생성자의 prototype을 참조하고 있는 프로퍼티 입니다.
function Student(grade, name) {
this.grade = grade
this.name = name
}
var gildong = new Student(3, '홍길동')
console.log(Student.prototype.constructor === Student)
console.log(Student.prototype === gildong.__proto__)
console.log(gildong.__proto__.constructor === Student)
true
true
true
프로토타입 체인
프로토타입도 객체입니다.
그렇기 때문에 프로토타입도 프로토타입을 프로퍼티로 가지고 있습니다.
그리고 그 프로퍼티 역시 또 다른 프로토타입을 프로퍼티로 가지고있습니다.
이말은 즉슨 하위 프로토타입은 상위 프로토타입의 프로퍼티와 메소드를 공유 받는다는 얘기입니다.
이런식으로 프로토타입이 상위 프로토타입까지 연결되는 구조를 프로토타입 체인이라고 합니다.
어, 그러면 무한재귀 아닌가? 라고 생각할 수 있습니다.
하지만 그건 아니고 프로토타입은 null을 프로토타입으로 가지고있는 객체에서 끝나게 됩니다.
예제를 통해 살펴보도록 하겠습니다.
function Student(grade, name) {
this.grade = grade
this.name = name
}
var gildong = new Student(3, '홍길동')
var proto1 = gildong.__proto__
console.log(proto1)
var proto2 = proto1.__proto__
console.log(proto2)
var proto3 = proto2.__proto__
console.log(proto3)
var proto4 = proto3.__proto__
console.log(proto4)
{}
[Object: null prototype] {}
null
prototype-chain.js:17
var proto4 = proto3.__proto__
^
TypeError: Cannot read property '__proto__' of null
보시다시피 null을 프로토타입으로 가지는 객체에서 끝나는 것을 볼 수 있습니다. null은 __proto__ 프로퍼티를 가지고 있지 않으며 프로토타입 체인의 종점 역할을 합니다.
자바에서 모든 객체가 Object 객체를 상속받는 것과같이 자바스크립트에서의 모든 객체 역시 Object 객체를 상속받습니다.
참고
- https://webclub.tistory.com/309
- https://www.zerocho.com/category/JavaScript/post/573c2acf91575c17008ad2fc
- https://goddaehee.tistory.com/231
- https://hanamon.kr/javascript-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EA%B3%BC-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%B2%B4%EC%9D%B8/
'JavaScript' 카테고리의 다른 글
[JavaScript] 콜백함수(Callback Function)란 (0) | 2022.03.17 |
---|---|
[JavaScript] Private Method 와 Field (0) | 2022.03.16 |
[JavaScript] 호이스팅이란 (0) | 2022.03.16 |
[JavaScript] for문 정리 (0) | 2022.03.16 |
[Javascript] 변수 선언 (0) | 2021.06.01 |