Это очень поможет, если вы отформатируете свой код:
> unsafeWindow.helloworld = function() {
>
> alert('Hello world!');
>
> // fails with error saying it does not exist
> helloworld2();
> }
>
> unsafeWindow.helloworld2 = function() {
>
> alert('Hello world!2');
>
> //fails with error saying it does not exist
> helloworld();
>
> }
Вы имеете бесконечно рекурсивную функцию - helloworld звонки helloworld2 , который вызывает helloworld и т. д. до бесконечности .
Но в любом случае вы устанавливаете свойство unsafeWindow
:
unsafeWindow.helloworld = function() {
, но затем пытаетесь вызвать его с помощьюнеквалифицированный идентификатор, который разрешается в цепочке областей действия:
[... later, in helloword2 ...]
helloworld();
Таким образом, идентификатор helloworld
разрешается в цепочке scope объекта выполнения / переменной, созданного, когда unsafeWindow.helloworld2
call.
Таким образом, helloworld
устанавливается как свойство из unsafeWindow
.Когда вызывается функция, идентификатор helloworld2
будет разрешен с использованием цепочки функции scope .
В браузерах объект window / global находится в цепочке областей действия, поэтому имена переменныхможет быть найден там (то есть переменные могут преобразовываться в свойства глобального объекта, если они не найдены раньше в цепочке областей действия), но я подозреваю, что когда вызывается unsafeWindow.helloworld
, его цепочка областей действия заканчивается глобальным объектом документа, а не unsafeWindow
.В противном случае вызовы функций в документе также будут иметь unsafeWindow
в их цепочке областей действия, что мне не кажется правильным.
Или я могу быть совершенно неправ в этом.: -)