Global object

From GreaseSpot Wiki
Jump to: navigation, search


In JavaScript, top-level functions and global variables are stored as properties of the global object. For a script on a webpage, the global object is the page's window, and thus functions or variables like

V = "V's value";
function F(){return "F's value"};

can be looked up through window. This gives the equivalences:

(V == window.V) && (V == window['V'])
(F == window.F) && (F == window['F'])

A Greasemonkey user script, however, by default wraps up all code inside an anonymous function wrapper that swallows identifiers, causing them not to end up on the global object. The useful effect of this wrapper is to protect user scripts from global identifiers in the Greasemonkey sandbox that might otherwise collide with yours and make it not work (yielding unhelpful errors such as "invalid value").

Historically it was also a measure to not unwittingly pollute the window object. 0.8.0 removed it and 0.8.1 re-added it by default, unless the script wright disables it manually using @unwrap. In the context of such a user script, the special operator this acts as "the global object is passed as the context object", which behind the scenes is also linked to the window object, which is in turn a XPCNativeWrapper wrapped version of unsafeWindow - the window of the user script's target page.


One consequence of being unable to access a user script's global object is that debuggers and inspectors are unable to see anything in a user script. In order to inspect a data structure in the script's scope it can be temporarily added to unsafeWindow. E.g.:

unsafeWindow.myScriptMyStruct = myStruct;

With the @unwrap header in place, you can export the whole global object in this fashion, which lets you inspect the whole running context of the script using such tools:

// ==UserScript==
// ...
// @unwrap
// ==/UserScript==

unsafeWindow.myScript = this;

After debugging this sort of binding should be removed to avoid security and scope related problems.