객체 공장장!
생성자 함수는 새로운 객체를 만들고 사용자가 요구하는 함수들을 구현할 수 있게 해주는데, 이렇게 생성된 객체를 인스턴스라고 한다.
new 연산자가 붙은 함수
인스턴스를 만들 수 있다
예)
new Object(), new Array()는 자스 내부적으로 존재하는 내장 생성자
new Object() <- 객체 타입의 인스턴스를 만들어주는 생성자 함수
new Array() <- 배열 타입의 인스턴스를 만들어주는 생성자 함수
let myArray = new Array(1, 2, 3);
console.log(myArray);
// (3) [1, 2, 3]
let book = {
책이름: 'JavaScript',
책가격: 1000,
저자: '곤',
출판일: '22.10.11'
}
let newBook = {}
newBook['책이름'] = 'JavaScript' // 예를 들어 form에서 입력 받은 값
newBook['책가격'] = 10000
newBook['저자'] = '곤, 곤곤, 곤곤곤'
newBook['출판일'] = '22.10.30'
function Book(책이름, 책가격, 저자, 출판일){
this.책이름 = 책이름
this.책가격 = 책가격
this.저자 = 저자
this.출판일 = 출판일
}
// this.책이름 여기의 책이름은 다르다 = 뒤에 책이름과 Book 뒤에 책이름이 묶인다
// let data = Book('CSS', 10, '곤', '22.12.30')
// console.log(data) // undefined
let book1 = new Book('HTML', 10, '곤', '22.12.30')
let book2 = Book('CSS', 20, '곤', '23.12.30')
let book3 = new Book('JS', 30, '곤', '24.12.30')
console.log(book1, book2, book3)
// [프로토타입 오브젝트]로 객체를 찍어내는 용도!
메모리상으로도 효율적, 코드도 깔끔
사용자가 직접 새로운 타입을 만들 수도 있다
function MyOwn(){}
<생성자 함수> (함수가 대문자로 시작! 소문자 문법 오류는 아닌데 개발자들끼리 약속)
let myObj = new MyOwn();
<인스턴스> <생성자>
생성자와 인스턴스의 관계는 instanceof와 constructor 메소드를 통해 확인
function MyOwn(){
}
let myObj = new MyOwn();
console.log(myObj instanceof MyOwn); // true
console.log(myObj.constructor === MyOwn); // true
function 함수를 선언해주는데 생성자 함수니까 MyOwn 대문자로 시작해주고
생성자 함수의 인스턴스를 참조할 myObj 변수를 선언해주고 new MyOwn(); 함수 실행
MyOwn이라는 타입의 인스턴스가 생겨서 myObj 변수가 참조할텐데
생성자와 인스턴스의 관계를 알아보자
console.log(myObj instanceof MyOwn);
myObj 변수가 MyOwn 생성자 함수의 인스턴스인가?
console.log(myObj.constructor === MyOwn);
myObj의 생성자가 MyOwn 함수인가?
생성자는 왜 만들까?
동일한 프로퍼티와 메소드를 가진 객체를 쉽게 대량생산!
function Food(taste){
this.taste = taste;
this.smell = function(){
console.log(this.taste + " 냄새가 난다.");
}
}
let myFood1 = new Food("특제 파스타");
myFood1.smell(); // "특제 파스타 냄새가 난다."
Food 생성자 함수(대문자 시작)는 taste 인수로 전달하고
Food 타입의 인스턴스가 만들어졌다~
myFood1 변수는 Food 타입의 인스턴스를 참조
myFood1은 smell이라는 함수도 실행할 수 있을 것
생성자의 new 연산자는 매우 중요
new 연산자가 붙으면 함수의 this는 인스턴스를 참조하게 되며,
new 연산자가 자동으로 인스턴스를 반환하기 때문에 함수 안에 return 연산자도 필요 없어지게 된다.
function Food(taste){
console.log(this);
this.taste = taste;
this.smell = function(){
console.log(this.taste + " 냄새가 난다.");
}
}
let myFood1 = new Food("특제 파스타");
let myFood2 = Food("특제 파스타")
console.log(this); 찍어보자
let myFood1 = new Food("특제 파스타");
//
Food {} [[Prototype]]: Object
알 순 없지만 Object를 가리키고 있고
let myFood2 = Food("특제 파스타")
//
Window {0: global, 1: global, 2: global, window: Window, self: Window, document: document, name: '', location: Location, …}
두번째는 window 전역객체를 가리키고 있다
function Food(taste){
console.log(this.constructor);
this.taste = taste;
this.smell = function(){
console.log(this.taste + " 냄새가 난다.");
}
}
let myFood1 = new Food("특제 파스타");
let myFood2 = Food("특제 파스타")
좀 더 정확하게 console.log(this.constructor);
찍어보면
첫번째는
ƒ Food(taste){
console.log(this.constructor);
this.taste = taste;
this.smell = function(){
console.log(this.taste + " 냄새가 난다.");
}
}
Food 안에 this가 가리키고 있는 생성자는 Food 함수
두번째는
ƒ Window() { [native code] }
윈도우 객체 생성하는 생성자 함수를 가리키고 있다
만약 생성자 함수에 new 연산자가 없다면 생성자 함수는 평범한 함수일뿐이며 this는 전역객체를 가리키게 된다