Your method of event dispatch is very common. NodeJS does it this way, as well as many other event dispatchers. It is also how I use to do it until I encountered a very nasty bug in Chrome DevTools.
Object A emits events.
Object B subscribes to A, and manages the lifetime of Object C
Object C subscribes to A in its constructor, and unsubscribes in its dispose function.
With the common event listener model, Object C could have its methods called after dispose was called, even though it appeared to clean up its event listener!
You can check out the DOM spec for the correct behavior, which both clones the event listeners arrray and sets a removed flag on them in case they were removed after cloning.