It would be beneficial if you could tidy up your code formatting:
> unsafeWindow.helloworld = function() {
>
> alert('Hello world!');
>
> // encounters error stating it doesn't exist
> helloworld2();
> }
>
> unsafeWindow.helloworld2 = function() {
>
> alert('Hello world!2');
>
> //fails with error saying it does not exist
> helloworld();
>
> }
You have an infinitely recursive function - helloworld calls helloworld2 which calls helloworld and so on indefinitely.
However, you are setting a property of unsafeWindow
:
unsafeWindow.helloworld = function() {
but then attempting to call it using an unqualified identifier that is resolved on the scope chain:
[... later, in helloword2 ...]
helloworld();
Therefore, the identifier helloworld
is resolved on the scope chain of the execution/variable object created when unsafeWindow.helloworld2
is called.
When the function is called, the identifier helloworld2
will be resolved using the scope chain of the function.
In browsers, the window/global object is on the scope chain so variable names may be found there (i.e. variables may resolve to properties of the global object if not found sooner in the scope chain). However, I suspect that when unsafeWindow.helloworld
is called, its scope chain ends with the document's global object, not unsafeWindow
.
Otherwise, calls to functions in the document would also have unsafeWindow
on their scope chain, which seems incorrect to me.
Or perhaps I am mistaken about that. :-)