#javascript #jquery #scope #closures
#javascript #jquery #область видимости #замыкания
Вопрос:
Я пишу приложение на javascript и не могу понять, как получить доступ к переменным, объявленным в моей функции, внутри этого синтаксического анализа jquery. Внутри я могу получить доступ к глобальным переменным, но я действительно не хочу создавать глобальные переменные для этих значений.
По сути, я хочу извлечь имена файлов из xml-документа в simulationFiles
переменной. Я проверяю, равен ли атрибут node simName
и извлекаю две строки внутри xml-элементов, эта часть, я думаю, работает.
Как я могу извлечь эти xml-элементы и добавить их к локальным переменным?
function CsvReader(simName) {
this.initFileName = "somepath";
this.eventsFileName = "somepath";
$(simulationFiles).find('simulation').each(function() {
if ($(this).attr("name") == simName) {
initFileName = $(this).find("init").text();
eventsFileName = $(this).find("events").text();
}
});
}
Ответ №1:
this
В CsvReader
функции это не то же самое, что this
в each()
обратном вызове (где вместо этого это текущий элемент в итерации). Чтобы получить доступ к области видимости внешней функции в обратном вызове, нам нужно иметь возможность ссылаться на нее под другим именем, которое вы можете определить во внешней области видимости:
function CsvReader(simName) {
this.initFileName = "somepath";
this.eventsFileName = "somepath";
var self = this; // reference to this in current scope
$(simulationFiles).find('simulation').each(function() {
if ($(this).attr("name") == simName) {
// access the variables using self instead of this
self.initFileName = $(this).find("init").text();
self.eventsFileName = $(this).find("events").text();
}
});
}
Комментарии:
1. Спасибо за быстрый ответ, но, к сожалению, это не работает. На самом деле я тоже пробовал это раньше, но внутри неназванной функции $self сообщается как не определенный firebug.
2. Это работает следующим образом! Извините за это, когда я сохранил this в переменную, у меня была другая ошибка после вызова этой функции, и когда я отлаживал, отладчик показал мне, что $self.initFileName внутри не определено, но на самом деле это работало, и я получил результат. Большое спасибо!
3. Предполагается, что ваши
this.initFileName
иthis.eventsFileName
являются локальными для вашей функции или для всей страницы? Nm … увидел ваш пост несколькими секундами позже. Рад, что это работает!4. @CantucciHQ: Потому что
this
вCsvReader
функции это не то же самое, чтоthis
вeach()
обратном вызове. Чтобы получить доступ к области видимости внешней функции в обратном вызове, нам нужно ссылаться на нее другим именем. Наличие$self
ссылки позволяет это сделать.5. @Cory Большое спасибо, это имеет смысл. Вчера я был еще более сбит с толку — я не находил переменные внутри $.each() с помощью инструментов разработчика Chrome. Но оказывается, что переменная не существовала внутри each(), потому что переменная еще не использовалась в each() ! Как только я добавил использование переменной в фактический код, все заработало хорошо.
Ответ №2:
Я сделал рабочую демонстрацию (я изменил ее на использование классов, чтобы она работала с HTML).
function CsvReader(simName) {
this.initFileName = "somepath";
this.eventsFileName = "somepath";
var context = this;
$(simulationFiles).find('simulation').each(function() {
if ($(this).attr("name") == simName) {
context.initFileName = $(this).find("init").text();
context.eventsFileName = $(this).find("events").text();
}
});
}
Комментарии:
1. Этот метод отлично сработал, спасибо! Извините, но ошибка отладчика немного подвела меня и показала, что это не работает.
Ответ №3:
Самое простое изменение, которое вы можете сделать, чтобы заставить его работать, это… Измените вашу функцию в каждой из них с обычной (function () {}) на функцию со стрелкой ( () => {}), которая автоматически примет контекст функции, в которой она определена.