Javascript variable scope - how exactly does it work?

I am trying to integrate a Javascript library ([DWV]
(https://github.com/ivmartel/dwv), an Image Viewer). The library is loaded using the @JavaScript annotation. Using the following code to load a test image, it works fine.

public DWV(){
        UI.getCurrent().getPage().executeJs("dwv.gui.getElement = dwv.gui.base.getElement;\n" +
                "var app = new dwv.App();\n" +
                "app.init({\n" +
                "    containerDivId: \"dwv\"\n" +
                "});\n" +
                "app.loadURLs([\"https://raw.githubusercontent.com/ivmartel/dwv/master/tests/data/bbmri-53323851.dcm\"]
);"
        );
    }

When trying to spin off the loading of the URL into a separate function, like this:

public DWV(){
        UI.getCurrent().getPage().executeJs("dwv.gui.getElement = dwv.gui.base.getElement;\n" +
                "var app = new dwv.App();\n" +
                "app.init({\n" +
                "    containerDivId: \"dwv\"\n" +
                "});\n"
        );
    }

    public void loadURL(){
        UI.getCurrent().getPage().executeJs("app.loadURLs([\"https://raw.githubusercontent.com/ivmartel/dwv/master/tests/data/bbmri-53323851.dcm\"]
);");
    }

I get a ReferenceError : app is not defined.

How exactly are the variables defined by the JavaScript in the Constructor accessible? I tried replacing app with window.app, but that just led to more errors.
I am using Vaadin 14.

In Vaadin 14 the javascript library are not global.
This means var app = new xxx() won’t work outside the executeJs.

You can use window.dwvapp = new xxx.
I would probably avoid to name a global variable app.

What is your error when you defined app variable as a global variable?

Can you share the entire class?

It’s not recommended to use UI.getCurrent().getPage().executeJs in a constructor and, especially if you have a lot of javascript, I would definitely create a separate javascript file.