The ECMAScript spec does not define which object should be the global in particular runtime environments. For browsers this is defined by the HTML5 spec. There is some special-casing for window
via the windowproxy object, but that should generally be invisible to javascript.
I.e. even if top level this !== window
in a browser script this does not necessarily stem from ecma spec properties or strict mode. It could also stem from from the html spec's definition what a global ought to be for that particular script environment or whether that global actually equals <local variable bindings>.window
.
An issue with your question is what you call the global scope. The spec has a concept of global lexical environment. But not all script bodies (source code) are evaluated with a realm's global lexical environment as their lexical environment.
A further complication is that that scripts can not just run in different lexical environments but that there can also be multiple realms which can interact and yet have distict globals.
This may seem like a non-issue because different code realms (e.g. workers or browser windows) mostly interact through small API surfaces, but reality is more complex than that. E.g. one realm can use a global object which has a prototype which is a proxy to a different realm's global. In many ways they will look like sharing a global when they actually are not and doing something like this == this.referenceToSelf
may return false. This commonly happens with firefox's sandboxes which are used to run addons/webextensions/userscripts.
A counterexample where a "top level" this
is not the global object would be es6 modules.
So there exists strict mode code where this
in the top level lexical is not the global object.
A much more trivial example is code eval'd in the context of a function. It inherits the this
from the function.