객체 자체에는 접근이 불가능해야함
객체에 대한 접근자(비공개 멤버: 클로저)를 사용해 실제 객체를 제어할 수 있다.
객체는 단 하나만 만들어지며, 해당 객체를 공유함
결국 인스턴스를 하나만 생성해 => 메모리 사용량을 줄이고, 불필요한 중복을 막는데에 있다.
아래와 같은 function이 있다고 가정하자
const onChangeHandler = () => {
const TextEncoder = new TextEncoder();
//TextEncoder를 이용해 추후 값을 검증하는 로직존재...
}
생성자 함수 자체의 this에 인스턴스를 저장하여 여러개의 인스턴스가 생성되는 것을 막는다.
이렇게 하면 객체의 인스턴스가 하나만 생성됨. function은 하나이고 이 자체의 바인딩된 this또한 유일하기 때문.
function Singleton() {
// Check if an instance already exists
if (Singleton.instance) {
return Singleton.instance;
}
// Properties or methods for the singleton instance
this.name = "Singleton Instance";
// Store the instance
Singleton.instance = this;
// Return the instance
return this;
}
// Usage
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
console.log(instance1.name); // Singleton Instance
console.log(instance2.name); // Singleton Instance
여기서 Singleton 함수는 즉시실행 함수로 구성되어있고, 클로저를 이용해 싱글톤 패턴을 구현한다.
먼저 instance 변수를 캡슐화하여 외부에서 접근하지 못하도록 막는다. (클로저)
Singleton변수에 할당된 function은 런타임에서 즉시 실행되고, 이 렉시컬 환경에 대한 참조값을 Singleton변수가 담고있다.
그렇기 때문에 함수가 실행될때마다 instance가 새로 생성되는게 아니라 instance자체가 동일한 값으로 취급 받을 수 있다는 것이다.
const Singleton = (function() {
// Private instance variable
let instance;
// Singleton constructor function
function Singleton() {
if (instance) {
return instance;
}
// Properties or methods for the singleton instance
this.name = "Singleton Instance";
// Save the instance to the private variable
instance = this;
return this;
}
return Singleton;
})();
// Usage
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
console.log(instance1.name); // Singleton Instance
console.log(instance2.name); // Singleton Instance
ES6부터는 Class 문법으로 싱글톤 패턴을 구현 할 수 있다.
원리는 위에 생성자함수와 크게 다르지 않다.
Class를 사용하면 Singleton 패턴이 더 깔끔하고 직관적이며 다른 메서드와 동일한 단일 인스턴스 보장한다.
class Singleton {
constructor() {
// Check if an instance already exists
if (Singleton.instance) {
return Singleton.instance;
}
// Initialize properties for the instance
this.name = "Singleton Instance";
// Store this instance in a static property
Singleton.instance = this;
// Return the instance
return this;
}
}
// Usage
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // true
console.log(instance1.name); // Singleton Instance
console.log(instance2.name); // Singleton Instance