Search code examples
javascriptfirefoxgreasemonkeyuserscripts

window.Object != Object for greasemonkey script


The following script logs false to the console. Does anyone know why or what benefits it brings?

From a brief glance into Greasemonkey's source code I couldn't find anything that modifies Object. Also looking into the Object it is hard to see any meaningful differences, all the functions are still native code.

// ==UserScript==
// @name        test
// @namespace   test
// @include     *
// @grant       none
// ==/UserScript==

console.log(window.Object == Object)

(tested on Greasemonkey & Firefox, not sure about Scriptish & Chrome, though any experiments welcome!).

[NOTE: this question is unrelated to the question of {a: 2} != {a: 2}, please read the question itself and not just glance at the title before you cast any close votes, thanks!].


Solution

  • This is a side effect of Mozilla's current sandbox process. Even in @grant none mode, Greasemonkey sandboxes scripts using Components.utils.Sandbox -- only with Xrays off and wantExportHelpers left at false.

    So, your window.Object == Object is equivalent to window.Object == this.Object.
    But: In a Greasemonkey script, this (the root/global this) is always a Sandbox object, not a Window.

    Firefox may have a good reason for cloning Object like that, but I couldn't find any reference saying as much.


    Chrome with Tampermonkey does not do this and window.Object == Object is true for Tampermonkey scripts regardless of the @grant setting.

    Chrome also does not do sandboxing the same way.