본문 바로가기
Language/JavaScript

프로토타입 패턴(Prototype Pattern) 예시 - 자바스크립트(JavaScript ES5 /ES6)

by DevPark 2024. 5. 8.

자바스크립트로 구현한 프로토타입 디자인패턴을 번역하여 소개합니다. 

상황과 그에 대한 솔루션을 객체지향적인 디자인패턴과 다르게 자바스크립트스럽게(?) 구현된 예제입니다.

객체지향적으로 설계한 코드도 확인할 수 있습니다.  

자세한 내용은 아래 원문을 참고해주세요.

 

JavaScript-Design-Patterns/GoF/idiomatic/Creational/Prototype at master · Badacadabra/JavaScript-Design-Patterns

:paperclip: ES5 + ES6 + CoffeeScript + TypeScript design patterns with some theory, real-world examples and UML diagrams - Badacadabra/JavaScript-Design-Patterns

github.com


개요 (Synopsis)

저는 뭔가를 주문할 때 종이 주문서를 받는 것을 좋아합니다.

당연히 중요한 주문일때는 주문서를 잃어버리고 싶지 않기때문에 복사본을 만들기를 원합니다.

 

I.. want ..everything..

 


문제 (Problem)

"new"를 사용하여 새 객체를 생성하는 것은 기존 객체를 복제하는 것과 같지 않습니다..

자바스크립트의 장점은 프로토타입 기반이라는 점입니다.

내장된 Object.create() 메서드를 통해 복제를 수행할 수 있습니다.

그러나 Object.create()만 사용하면 제대로 복제할 수 없습니다.

이 메서드의 매개변수(원본 객체)는 새 객체의 프로토타입으로 사용됩니다.

이는 새 객체가 원본 객체와 같은 속성을 가지지 않을 것을 의미합니다.

이러한 속성은 새 객체에서 사용할 수 있지만 프로토타입에 존재하기 때문입니다.

암튼 다름


해결방법 (Solution)

이 상황에서 두 가지만 있으면 해결할 수 있습니다.

 

1. 복제하고자 하는 객체(리터럴) (ex: 주문서)
2. 복제할 객체를 매개변수로 받는 사용자 정의 복제 함수

 

참고: 

대부분의 경우에는 JavaScript에서 객체의 정확한 복사본을 가지는 것이 실제로는 유용하지 않습니다. 

중요한 것은 종종 여러 객체에서 동일한 속성을 사용할 수 있다는 것입니다.

일반적으로 Object.create()를 사용하는 것으로도 충분합니다.


ES5 버전 

Client  코드 (client.js)

'use strict';

var photocopy = require('./API/photocopy');

// ==============================
// CLIENT CODE 
// ==============================

var invoice = {
	price: 42,
    currency: "€"
};

var copy = photocopy(invoice);

console.log(copy.price); // 42
console.log(copy.currency); // €
console.log(copy === invoice); // false (copy는 원본 invoice가 아닙니다. 새로운 객체입니다!)

 

API 코드 (photocopy.js)

'use strict';

// ==============================
// PROTOTYPE
// ==============================

module.exports = function (invoice) {
	// 여기서는 속성이 항상 enumerable, writable 및 configurable로 가정합니다.
    // 그렇지 않은 경우에는 Object.defineProperty()와 Object.getOwnPropertyDescriptor()를 함께 사용해야 합니다.
    var clone = Object.create(Object.getPrototypeOf(invoice));
	for (var prop in invoice) {
		if (invoice.hasOwnProperty(prop)) {
    		clone[prop] = invoice[prop];
		}
	}
    return clone;
};

ES6 버전 

Client  코드 (client.js)

import photocopy from './API/photocopy';

// ==============================
// CLIENT CODE 
// ==============================

let invoice = {
	price: 42,
    currency: "€"
};

let copy = photocopy(invoice);

console.log(copy.price); // 42
console.log(copy.currency); // €
console.log(copy === invoice); // false (copy는 원본 invoice가 아닙니다. 새로운 객체입니다!)

 

API 코드 (photocopy.js)

// ==============================
// PROTOTYPE
// ==============================

export default invoice => Object.assign(Object.create(Object.getPrototypeOf(invoice)), invoice);
반응형

댓글