Hi bitli,
this is like being able to read a file after closing it.
Exactly. That's how the ImageWindow.windows array works in PJSR. Bear in mind that image windows and views are quite complex objects, and their relations with the rest of the platform are intricate and delicate. PI is a multithreaded environment. We cannot simply destroy a window asynchronously at the point we want, because that would generate lots of problems and leave many objects unstable. For the same reason, we cannot remove a still living window from the global window container arbitrarily.
GUI objects (as image windows and views) can only be destroyed when the event processing loop gains control. This happens naturally in a running GUI application or script during idle states, but not in code like this snippet. In PCL-based modules, calling ProcessInterface::ProcessEvents() normally flushes all pending events immediately, since the PI core application has a synchronous garbage collector. In the case of PJSR, however, we have an additional problem: an object's destructor won't be invoked until the JavaScript garbage collector (asynchronous) decides to destroy it. For this reason, calling processEvents() in the above code does not work: we have two garbage collectors working in sequence: JS's asynchronous collector first, and then PI Core's synchronous collector, which requires at least a run of the main event loop to destroy a GUI object.
This is a limitation of the JavaScript runtime, along with limitations of the PixInsight Core application. However, in the next version of the core there will be more robust and efficient ways to know if a given window or view has been closed, which will facilitate these tasks.