📌 생성자 함수 (constructor function)
- 객체를 생성하기 위한 함수
- 유사한 객체 여러 개를 쉽게 만들 수 있다.
- 일반함수와 구분하기 위해 'new' 연산자를 사용해 호출하고, 첫 번째 문자를 대문자(파스칼 케이스)로 작성한다.
new 연산자
- 빈 객체를 생성한다.
- 새로 생성된 빈 객체는 생성자의 프로토타입을 상속받는다.
- this를 새로 생성된 객체에 바인드 시킨다.
- 생성자에 명시적으로 다른 객체를 리턴하지 않는 경우, this로 바인드된 객체가 반환된다. (일반적으로 생성자는 값을 리턴하지 않음)
function User(name) {
// this = {}; (빈 객체가 암시적으로 만들어짐)
// 새로운 프로퍼티를 this에 추가함
this.name = name;
this.isAdmin = false;
// return this; (this가 암시적으로 반환됨)
}
let user = new User("보라");
// = let user = {
// name: "보라",
// isAdmin: false
// };
alert(user.name); // 보라
alert(user.isAdmin); // false
생성자 함수 참고: https://ko.javascript.info/constructor-new#ref-1199
1. 프로토타입 (Prototype)
- 자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어있고, 이 부모 객체를 프로토타입이라고 한다.
- 생성자 함수로부터 생성된 객체들이 공유할 수 있는 속성과 메서드를 정의한다.
- 쉽게 말하면 상위객체로 부터 상속 받은 것이라고 생각하면 됨!
function Person (name) { // Person은 생성자 함수
this.name = name;
}
Person.prototype.introduce = function () {
return "Hello, I am " + `${this.name}`;
}
// introduce는 Person.prototype에 정의된 메서드로 생성자 함수인 Person객체들이 공유할 수 있다.
const person1 = new Person("Jonh Doe");
person1.introduce(); // Hello, I am John Doe
// 따라서 person1은 introduce 메서드를 상속받아 사용할 수 있다!
// person1은 'instance'
function User(first, last) {
this.firstName = first
this.lastName = last
}
User.prototype.getFullName = function () {
return `${this.fistName} ${this.lastName}`
}
// firstName, lastName은 user함수가 실행될 때 마다
// 다른내용이 들어오기때문에 통일해서 메모리 관리를 할 수 없다.
// getFullName은 로직이 똑같기 때문에 여러번 작성하지 않고 통일화해서 관리
const john = new User('John', 'Doe')
const amy = new User('Amy', 'Clarke')
console.log(john.getFullName) // John Doe
console.log(amy.getFullName) // Amy Clarke
2. 인스턴스 (Instance)
- new 키워드를 통해 생성자 함수로 실행한 결과를 반환해서 할당된 그 변수를 생성자 함수의 instance 라고 한다.
- instanceof 연산자를 사용해, 객체가 특정 생성자 함수의 인스턴스인지 확인할 수 있다.
function User(first, last) {
this.firstName = first
this.lastName = last
}
User.prototype.getFullName = function () {
return `${this.fistName} ${this.lastName}`
}
const john = new User('John', 'Doe')
const amy = new User('Amy', 'Clarke') // john, amy는 User의 instance.
console.log(john.getFullName) // John Doe
console.log(amy.getFullName) // Amy Clarke
console.log(john instanceof User); // true
console.log(amy instanceof User); // true
여기서 john과 amy가 생성자 함수 User의 instance이고, User의 프로토타입 체인을 따라 메서드와 속성을 상속받는다.
📌 Class
- ES6 부터 사용할 수 있게 된 클래스는 생성자 함수와 프로토타입 메서드를 보다 직관적으로 작성할 수 있게 한다.
- prototype을 사용해서 new라는 키워드와 함께 생성자 함수로 인스턴스를 만들어 내는 개념
- 객체를 생산하는(찍어내는) 의미에서 붕어빵 틀에 자주 비유된다.
이걸 듣을 때 마다 내 머리 속 :
맛있겠다 ...🤤 ㅎ
1. class의 사용법
- class 키워드 + 이름 + 중괄호
- 클래스의 결과물은 인스턴스를 생성하는것.
- 생성자를 이용한 타입 생성과 그 결과가 정확하게 일치한다.
function User(first, last) {
this.firstName = first
this.lastName = last
}
User.prototype.getFullName = function () {
return `${this.fistName} ${this.lastName}`
}
const john = new User('John', 'Doe')
const amy = new User('Amy', 'Clarke')
console.log(john.getFullName) // John Doe
console.log(amy.getFullName) // Amy Clarke
프로토타입 설명에서 작성된 위의 함수를 Class 문법으로 다시 작성 ↓
class User {
constructor(first, last) {
this.firstName = first
this.lastName = last
}
getFullName() { // 위처럼 prototype 사용하지 않고 정의가능.
return `${this.fistName} ${this.lastName}`
}
}
const john = new User('John', 'Doe')
const amy = new User('Amy', 'Clarke')
// new라는 키워드를 통해서 생성자 함수로 실행한 결과를 반환해서 할당된 그 변수를
// 생성자 함수의 instance라고 부름. (여기서는 john,amy가 instance에 해당)
console.log(john.getFullName) // John Doe
console.log(amy.getFullName) // Amy Clarke
class 참고: https://typescript-kr.github.io/pages/classes.html
2. class 상속하기
- extends 키워드를 사용해 class를 상속 받는다. (extend: 확장)
- 상속받은 기존 클래스의 기능을 재사용, 필요에 따라 자식 클래스에서 기능을 추가하거나 변경 할 수도 있다.
(= 메소드 오버라이딩) - 코드의 재사용성과 유지보수성이 높아짐.
class Vehicle {
constructor(name, wheel) {
this.name = name
this.wheel = wheel
}
}
const myVehicle = new Vehicle('운송수단', 2)
console.log(myVehicle)
// {
// "name": "운송수단",
// "wheel": 2
// }
class Bicycle extends Vehicle {
constructor(name, wheel) {
super(name, wheel)
// 1.확장된 Vehicle이 여기서 실행되므로 super의 인수로 사용되는
// name, wheel은 Vehicle의 constructor(name, wheel)로 가게됨.
// 2.위에서 '운송수단', 바퀴의 개수(2)를 넣어준 것처럼 인수를 넣어주면
// 함수영역안의 constructor(name, wheel)로 받아서 다시 super(name, wheel)로 넘겨줌.
// 3. 1의 설명처럼 super은 확장된 Vehicle이기 때문에 Vehicle의 내용이 실행됨.
}
}
const myBicycle = new Bicycle('삼천리', 2)
const daughterBicycle = new Bicycle('세발', 3)
console.log(myBicycle)
console.log(daughterBicycle)
// {
// "name": "삼천리",
// "wheel": 2
// }
// {
// "name": "세발",
// "wheel": 3
// }
class Bicycle extends Vehicle
⇒ 여기서 Vehicle을 부모 클래스(슈퍼 클래스), Bicycle을 자식 클래스(서브 클래스) 라고 한다.
super (name, wheel)
⇒ super(): 부모 클래스(슈퍼 클래스)의 constructor를 호출한다.
// 기존의 내용을 가지고 추가적인 내용만 일부 작성한 예시
class Car extends Vehicle {
constructor(name, wheel, license) {
super(name, wheel)
this.license = license
}
}
const myCar = new Car('벤츠', 4, true)
const daughtersCar = new Car('포르쉐', 4, false)
console.log(myCar)
console.log(daughtersCar)
💡 메서드 오버라이딩
부모클래스의 메서드를 내가 새롭게 정의하는 것
클래스 상속 참고: https://ko.javascript.info/class-inheritance
3. Private
- 변수앞에 _ (언더스코어)를 붙이면 'class 안에서만 쓰겠다'는 접근제어, 읽기 전용의 의미
⇒ but 강제사항이 아니기 때문에 언더스코어를 사용해도 변경이 가능 - 이를 막기 위해서 JS에서는 _ 대신 #을 사용한다.
⇒ 개발자 도구에서는 #을 했어도 접근이 가능하기 때문에 html파일에서 실행 추천 - TS에서는 _ 대신 private을 사용한다.
- 객체 안의 중요한 정보를 안전하게 보호하여 프로그램이 뜻하지 않게 변경되는 것을 막는 역할
class Car {
#apiKey = '1234' // 접근제어
}
💡 private과 public을 나누는 이유: 불필요한 부분이나 세부적인 기밀까지 사용자에게 노출되는 것을 막기 위해
private 메서드,프로퍼티 참고: https://ko.javascript.info/private-protected-properties-methods
'TIL archiving ···.ᐟ > JavaScript + TypeScript' 카테고리의 다른 글
[노트내용정리] DOM과 이벤트 (0) | 2024.10.04 |
---|---|
[노트내용정리] this & 콜 어플라이 바인드 (Call, Apply, Bind) (2) | 2024.08.31 |
[노트내용정리] Iterable객체와 유사 배열 객체 (1) | 2024.08.31 |
[노트내용정리] 전개 연산자(Spread Operator) & 구조 분해 할당(Destructuring) (0) | 2024.08.29 |
[노트내용정리] 조건문과 반복문 (0) | 2024.08.28 |