#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:
Я столкнулся с такой же проблемой с закрытиями и создал эту скрипку, чтобы поэкспериментировать с различными способами вызова других функций в закрытии.
Я, наконец, остановился на этом формате:
(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, который, возможно, является тем, что вам было нужно?