我在 trace 專案時看到這一段

import * as os from 'os';
import * as winston from 'winston';
import { LoggerService } from '@nestjs/common';
import { utilities as nestWinstonModuleUtilities, WinstonModule } from 'nest-winston';
import { format, transports } from 'winston';
import { LoggingWinston } from '@google-cloud/logging-winston';
 
let logger: LoggerService;
 
export function getLogger(serviceName: string): LoggerService {
  // singleton pattern
  if (logger) {
    return logger;
  }
  logger = WinstonModule.createLogger({ format: format.json(), transports: transportsOption });
  return logger;
}
 

但我想說奇怪,竟然還可以這樣寫嗎,不就是利用 closure,我原本理解的是只能用 class 做,像是這樣

class Singleton {
  static #instance = null;
 
  constructor() {
    if (Singleton.#instance) {
      return Singleton.#instance;
    }
    // class 的初始化邏輯寫這邊
    this.value = 'hello singleton';
    Singleton.#instance = this;
    // 實例會被快取,之後 new 會直接回傳同一份
  }
 
  static getInstance() {
    if (!Singleton.#instance) {
      Singleton.#instance = new Singleton();
    }
    return Singleton.#instance;
  }
}
 

但我剛剛理解為 closure 也是錯的,應該是 ES module scope ES Module Singleton vs Class Singleton In JS