Helma Logo
main list history

on Helma 1.6.x and the scope of source code in "prototype" folders.

*.js files used in helma have a different and potentially confusing model for scope compared to client side javascript.

The basics:

In traditional client side scripting, the outermost scope in a Javascript source file is the global object. the keyword "this" also refers to that same global object in the outermost scope. In helma, this is only the case when a javascript source file is treated as a single file repository, or if it's in the "Global" folder of a multifile repository. In the case of javascript source files in a "prototype" folder however, the scopes do some interesting things.

A prototype folder is a named folder in a multifile repository. When such a repository is added to an application, new native Java functions are added to the application's global scope, with the same names as the folders in the repository. These are the constructor functions, and calling one of them with the "new" operator produces a new HopObject.

So for example, if a repository has a folder named "Page", the application's global scope gets a function also called "Page", and the code "new Page()" returns a new HopObject whose prototype is set to the value of Page.prototype.

Now here's where things get interesting. If you place a Javascript source file in that Page folder, with a .js extension, the outermost scope for that source file is in fact, Page.prototype. The keyword "this" also refers to Page.prototype. This is nearly as advertised in all the Helma documentation. This makes it so that if you define a function in the source file, it becomes a new property of Page.prototype, and through Javascript prototypal inheritence, becomes a property of every instance of "Page".

The tricky and confusing part of all this is that this special prototype scope is not transferred to the interior of Page's function declarations. Instead, inside of a prototype's function, the scope is reset to the global object, and "this" naturally refers to whatever instance of "Page" you happen to call it on. So a bit of code like this, which may be considered normal on the client side:

var title = "Untitled Page"
function printTitle() {
print(title);
}

doesn't work, unless you change it to something like this:

var title = "Untitled Page"
function printTitle() {
print(this.title);
}