Проблемы контекста IIFE - PullRequest
       15

Проблемы контекста IIFE

8 голосов
/ 05 октября 2011

В следующей конструкции:

(function(){

    var x = function(){
        alert('hi!');
    }

    var y = function(){
        alert("hi again!");
    }

    this.show = function(){
        alert("This is show function!");
    }

})();

Почему this относится к window объекту? Должно ли все внутри IIFE быть изолированным от глобального масштаба? Функции x и y также являются свойствами глобального объекта window?

Также, даже если я использую, поставьте var h = ... в начале:

var h = (function(){

    var x = function(){
        alert('hi!');
    }

    var y = function(){
        alert("hi again!");
    }

    this.show = function(){
        alert("This is show function!");
    }

})();

this все еще относится к объекту окна - я могу просто вызвать show() из глобальной области видимости! Как получилось?

Ответы [ 2 ]

10 голосов
/ 05 октября 2011

@ Пойнти прав, но он не представляет всю проблему - вас может заинтересовать этот связанный ответ .Проблема здесь в том, что если вы не используете ключевое слово new, вы не создаете экземпляр объекта, поэтому для this нет экземпляра для ссылки.В отсутствие экземпляра this относится к объекту window.

В общем случае вам не нужно this внутри IIFE, поскольку у вас есть прямой доступ к любой определенной функции или переменнойв области действия анонимной функции - show() может вызывать x() и y() напрямую, поэтому нет необходимости в this ссылке.Может быть действительный вариант использования для создания IIFE с new, но я никогда не сталкивался с этим.

10 голосов
/ 05 октября 2011

Глобальный контекст (window в браузере) - это значение, которое this получает, когда нет другого значения для использования.

Ваши локальные переменные являются локальными (то есть не свойствами window). Они объявлены внутри функции с var.

Причина, по которой добавление var h = (function(){... не имеет значения, заключается в том, как вы вызываете функцию. Ссылка на функцию не является значением свойства объекта (например, something.func()), и вы не вызываете его с помощью .call() или .apply(), поэтому это относится к глобальному (window) объекту. Это просто способ определения языка.

...