함수를 선언해서 함수 내부에서 객체를 생성해 반환하는 함수를 말합니다.
처음 함수를 호출할 때만 인수를 전달하고 이후에는 함수 내부에 있는 객체에 접근할 때
인수 전달이 필요하지 않고, 필요하다면 프로퍼티에 접근해서 값을 수정할 수 있습니다.
⭐ 팩토리함수 생성 방식
팩토리 함수는 보통 객체 리터럴 형태로 객체를 생성하는 것과는 달리, 동적으로 객체를
생성합니다. 팩토리 함수는 매개변수를 받아서 새로운 객체를 생성하고, 이를 반환합니다.
따라서 팩토리 함수를 사용하면 객체 생성에 필요한 로직을 모듈화하고, 재사용성을 높일
수 있습니다.
👉 색상에 관련된 팩토리 함수
function makeColor(r,g,b){
const color = { };
color.r = r;
color.g = g;
color.b = b;
color.rgb = function () {
console.log(this);
return `rgb(${r}, ${g}, ${b})`;
}
return color;
}
const colorList = makeColor(15,20,25);
/*
동작 원리
1. 함수를 호출하고 함수 내부에서 객체를 생성하고 전달받은 매개 변수로 객체의 프로퍼티에 값을 할당합니다.
2. 마지막으로는 color 객체를 반환합니다.
3. rgb() 메서드를 호출하면 사용자가 전달한 색상값을 템플릿 리터럴을 사용해 rgb값으로 반환합니다.
* 반환하기 이전에 this를 호출하는데, 이유는 this를 구조분해하고 분해된 r,g,b 변수를 반환하기 위함입니다.
*/
this
를 출력해보면 함수를 호출한 colorList 상수에 객체가 반환되었기에 반환된 객체에
대한 프로퍼티에 접근할 수 있습니다.
👉 this를 이용한 팩토리 함수
function makeColor(r, g, b) {
const color = {};
color.r = r;
color.g = g;
color.b = b;
color.rgb = function () {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
return color;
}
const colorList = makeColor(15, 20, 25);
const purple = makeColor(35, 200, 250);
/*
동작원리
1. 동작과정은 위에서 팩토리함수를 생성한 첫 번째 방법과 동일합니다.
다만 this를 구조분해하고 분해된 변수를 이용해서 rgb값을 설정하는 방법만 다릅니다.
*/
이런식으로 팩토리함수를 생성하면 함수 내부에서 객체를 생성해서 반환할 수 있기에
청사진같은 개념으로 여러 변수에서 함수를 호출해서 원하는 색상을 추출할 수 있습니다.
그리고 메서드를 호출할 때, 인수를 전달할 필요가 없다.
생성자 함수로 인해 팩토리함수 패턴은 이제 자주 사용되지 않습니다.
함수가 호출될 때 마다, 함수 내부에서 동일한 메서드가 계속해서 생성된다.
아래 예제를 확인 해보자.
👉 팩토리 함수
function makeColor(r, g, b) {
const color = {};
// 함수를 호출할 때 마다 새로운 객체를 생성
color.r = r;
color.g = g;
color.b = b;
color.rgb = function () {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
// 함수를 호출할 떄 마다 메서드가 계속 생성됩니다.
// ( 함수가 호출될 때 해당 메서드가 계속 재생성 될 필요는 없다 )
return color;
}
const blackColor = makeColor(0,0,0);
blackColor.rgb();
const greenColor = makeColor(0,255,0);
greenColor.rgb();
우리가 생성한 함수를 살펴보면 함수가 호출될 때 마다
.rgb()
라는 메서드가 재생성
된다. 하나의 프로토타입에서 공유하는 메서드가 아니기 때문에 makeColor() 함수를
호출하고 반환 값을 가지는blackColor
,greenColor
상수는 서로 다른 메서드를
참조하기에 일치하지 않다.
하지만 문자열에 관련된 메서드인slice
는 문자열마다 메서드를 갖고 있는 것이
아니라, 문자열에 관련된 프로토타입에서 해당 메서드를 보유하고 있기에 서로다른
문자열 일지라도 같은 메서드를 참조하고 있는 것을 확인할 수 있다.
👉 팩토리 함수
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
console.log(this);
}
Color();
/*
팩토리 함수에서 this는 전역객체(Window)를 참조합니다.
그리고 팩토리 함수(일반함수)는 빈 객체를 생성하지 않습니다.
*/
👉 생성자 함수
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
console.log(this);
}
new Color();
/*
생성자 함수 생성 원리
1. Color.prototype을 상속하는 새로운 객체가 생성된다.
2. Color 함수 내부에서 this {} 라는 빈 객체가 생성되고 this가 반환된다.
3. this 객체의 이름은 자신을 호출한 함수명이 된다.
*/
일반 함수의
this
는 전역 객체를 참조하고, 생성자 함수의this
는 자신을 호출한
함수명의 객체를 참조한다. 생성자 함수의 프로토타입을 확인해보면 Color로 설정된
생성자 특성이 있다. 함수를 사용해서 생성자를 객체나 다른 객체에 설정할 수 있다.
초록색박스가 일반 함수의 this 결과 값이고 빨간색 박스가 생성자 함수의 this 값이다.
👉 프로토타입에 메서드 추가
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
/* 생성자함수 Color에 대해서 메서드를 프로토타입으로 추가 */
Color.prototype.rgb = function () {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
const color1 = new Color(10, 20, 255);
color1.rgb();
// Color 생성자 함수에 rgb() 라는 메서드가 프로토타입으로 추가되어서 color1 변수도 메서드에 접근할 수 있다.
서로 다른 객체에서도 같은 생성자(Color)를 가지므로 rgb() 메서에 접근할 수 있고,
동일한 프로토타입의 메서드를 사용하므로 일치한다고 표시됩니다.
생성자 함수를 사용하면 호출 마다 고유의 메서드를 추가해서 사용할 필요가 없어집니다.
👉 색상 불투명도를 결정하는 rgba를 프로토타입 메서드로 추가
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
Color.prototype.rgb = function () {
const { r, g, b } = this;
return `rgb(${r}, ${g}, ${b})`;
}
/* 사용자로부터 전달받은 매개변수가 없을 경우에는 a의 기본값을 1로 설정 */
Color.prototype.rgba = function (a=1) {
const { r, g, b } = this;
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
const color1 = new Color(10, 20, 255);
color1.rgba(0.5);
사용자로부터 전달받은 매개변수가 없을 경우에는 기본값(1)로 설정되고, 매개변수가
있는 경우에는 해당 값으로 불투명도가 설정된다.
Color 함수를 사용하는 객체들은 동일한 프로토타입을 가지므로, Color에 관련된 모든
인스턴스에서 메서드를 사용할 수 있다.