Using closures to manually "extend" a class in JavaScript/TypeScript

49 views Asked by At

This isn't so much a problem I'm having, rather than a general question about how classes/prototypes work in JS vs using closures. Lets say I have the following class (I'm going to omit the full body's of the methods as they are besides the point)...

export class SongDisplayer extends EventEmitter{
  mediaPath: string;
  currentlyPlaying: string;

  constructor(hlsMediaPath: string){
    super();
    this.mediaPath = hlsMediaPath;
    this.currentlyPlaying = '';

    this.on('currentlyPlaying', (songInfo) => {
      this.currentlyPlaying = songInfo;
    });
  };

  
  async queueDisplaySong(
    songInfo: string
  ): Promise<undefined>{
    
    const segments = await this._getM3u8Segments(this.mediaPath);

    if (!segments){
      this.emit('currentlyPlaying', songInfo);
      return;
    };

    ......
  };


  async _getM3u8Segments(
    mediaPath: string
  ): Promise<string[]>{

   ........
  };

   ......
};

I figure I can represent the same/similar behavior as the extends keyword by doing the following...

export function MakeSongDisplayer(
  mediaPath: string
){
  const eventEmitter = new EventEmitter();
  let currentlyPlaying = '';

  eventEmitter.on('currentlyPlaying', (songInfo) => {
    currentlyPlaying = songInfo;
  });

  return {
    queueDisplaySong: (songInfo: string) => {
      queueDisplaySong(
        songInfo,
        mediaPath,
        eventEmitter
      );
    },
    on: (event: string, cb: (...args: any) => any) => {
      eventEmitter.on(event, cb);
    },
    getCurrentlyPlaying: () => currentlyPlaying
  };
};


async function queueDisplaySong(
  songInfo: string,
  mediaPath: string,
  eventEmitter: EventEmitter
): Promise<undefined>{
  
  const segments = await _getM3u8Segments(mediaPath);

  if (!segments){
    eventEmitter.emit('currentlyPlaying', songInfo);
    return;
  };

  ......
};

What would the potential drawbacks of doing something like the later be? My intuition is that there is probably a higher memory overhead if I where to create many of these "class" instances, because the functions in the returned "dispatch" object are duplicated on every call rather that referencing a function via the prototype chain. But I'm not clear if that's whats happening or if possibly my understanding of prototype's are fuzzy. Would love to hear any thoughts or insights!

0

There are 0 answers