Проблема с закрытием JS

#javascript #oop #closures

#javascript #ооп #закрытия

Вопрос:

У меня есть этот js:

 (function () {

    Namespace = {

        settings: {
            myVar: 'test' 
        },

        init: function() {

            var memberSearchFrm = document.getElementById('memberSearch');
            memberSearchFrm.onsubmit = function() {

                this.someOtherFunction(); // doesn't work
                console.log(this.settings.myVar); // doesn't work 
            }
         },

        someOtherFunction: function() {
            console.log('test');  
        }
    }

    Namespace.init();
})();
  

Я теряю контекст «этого», когда захожу в свою функцию onSubmit. Можете ли вы помочь мне понять, почему это происходит и как обойти эту ситуацию?

Ответ №1:

Попробуйте этот трюк.

Перед закрытием задайте переменной с именем ‘that’ значение this.

 var that = this;
  

Затем используйте это в вашем закрытии. Проблема, с которой вы столкнулись, заключается в том, что закрытие привязано к вашему DOM-узлу, а не к вашему объекту. Итак, когда вы вызывали closure, это имело значение узла DOM.

Комментарии:

1. Я бы рекомендовал вызвать его self .

2. Мне тоже больше нравится self, но я думаю, что «это» больше похоже на Java, и все хотят, чтобы JavaScript был Java.

3. также self является ключевым словом в javascript, ссылающимся на текущее окно — jsfiddle.net/GvKZ4

4. Если вы используете var self = this, то self находится только в области видимости внутри функции.

Ответ №2:

Внутри memberSearchFrm.onsubmit , this ссылается на memberSearchFrm , а не на объект, который вы хотите. Вам нужно сохранить ссылку на this .

     init: function() {
        var that = this;
        var memberSearchFrm = document.getElementById('memberSearch');
        memberSearchFrm.onsubmit = function() {
            that.someOtherFunction();
            console.log(that.settings.myVar); 
        }
     },
  

Ответ №3:

Я столкнулся с такой же проблемой с закрытиями и создал эту скрипку, чтобы поэкспериментировать с различными способами вызова других функций в закрытии.

http://jsfiddle.net/7FzEz/5/

Я, наконец, остановился на этом формате:

 (function () {

     var obj = {

        settings: {
            myVar: 'test' 
        },

        init: function() {

            var memberSearchFrm = document.getElementById('memberSearch');
            memberSearchFrm.onsubmit = function() {

                obj.someOtherFunction(); 
                console.log(obj.settings.myVar);  
            }
         },

        someOtherFunction: function() {
            console.log('test');  
        }
    }

    obj.init();
})();
  

Комментарии:

1. Пространство имен было просто именем-заполнителем для использования в моем примере. Какое преимущество дает ему включение var? Это работает в любом случае, j / c…

2. На самом деле, в вашем случае ничего подобного, поскольку вы находитесь в анонимной оболочке, и я отредактирую это здесь. Когда вы не находитесь в анонимной оболочке, это имеет значение — смотрите проклятие глобальных переменных в области видимости здесь: bonsaiden.github.com/JavaScript-Garden/#function.scopes

3. Теперь я беру свои слова обратно, добавление var в действительно имеет значение, поскольку это не позволяет вам загрязнять ваше глобальное пространство имен: jsfiddle.net/vtPuE

4. Конечно …. если вы хотите назначить его этому пространству имен в глобальном контексте, вам не нужен var, который, возможно, является тем, что вам было нужно?