Вопрос или проблема
Я получаю ошибку “Uncaught ReferenceError: Cannot access ‘Q12’ before initialization” внутри функции changeCssClassIfOldAndNewValuesAreDifferent. Есть идеи, почему? Спасибо.
const formController = (function () {
return {
'changeCssClassIfOldAndNewValuesAreDifferent': changeCssClassIfOldAndNewValuesAreDifferent
};
const formScope: any = $("form#userAnswerForm");
const Q12: any = $('.persistable[id=Q12]', formScope);
const Q23: any = $('.persistable[id=Q23]', formScope);
function changeCssClassIfOldAndNewValuesAreDifferent() {
$('input.persistable, select.persistable').not(Q12) //<---Ошибка ссылки
.each(function () {
console.log('каждый элемент ввода и выбора с классом persistable (изменение, mouseout)');
const thisPersistable: any = $(this);
const Q12_or_Q23_is_not_empty: boolean = !commonUtility.isEmpty(Q12) &&
!commonUtility.isEmpty(Q23);
...
...
});
}
})();
$(function(){
formController.changeCssClassIfOldAndNewValuesAreDifferent();
});
Короче говоря, вам просто нужно переместить объявление перед возвратом, потому что в возврате вы вызываете функцию, которая пытается получить доступ к Q12, которое объявлено после возврата.
const formController = (function () {
const formScope: any = $("form#userAnswerForm");
const Q12: any = $('.persistable[id=Q12]', formScope);
const Q23: any = $('.persistable[id=Q23]', formScope);
return {
'changeCssClassIfOldAndNewValuesAreDifferent': changeCssClassIfOldAndNewValuesAreDifferent
};
function changeCssClassIfOldAndNewValuesAreDifferent() {
$('input.persistable, select.persistable').not(Q12) //<---Ошибка ссылки
.each(function () {
console.log('каждый элемент ввода и выбора с классом persistable (изменение, mouseout)');
const thisPersistable: any = $(this);
const Q12_or_Q23_is_not_empty: boolean = !commonUtility.isEmpty(Q12) &&
!commonUtility.isEmpty(Q23);
...
...
});
}
})();
$(function(){
formController.changeCssClassIfOldAndNewValuesAreDifferent();
});
Ответ или решение
Проблема, с которой вы столкнулись, заключается в том, что вы пытаетесь получить доступ к переменной Q12
до её инициализации. Это происходит из-за того, что вы определяете Q12
и Q23
после оператора return
, в то время как функция changeCssClassIfOldAndNewValuesAreDifferent
, возвращаемая из функционального выражения, использует Q12
. В JavaScript, благодаря механизму поднятия (hoisting), переменные, объявленные с помощью const
и let
, не доступны до момента их объявления.
Чтобы исправить эту ошибку, вам нужно переместить объявления переменных Q12
и Q23
выше оператора return
. Вот исправленный код:
const formController = (function () {
const formScope = $("form#userAnswerForm");
const Q12 = $('.persistable[id=Q12]', formScope);
const Q23 = $('.persistable[id=Q23]', formScope);
function changeCssClassIfOldAndNewValuesAreDifferent() {
$('input.persistable, select.persistable').not(Q12) // Здесь ошибка больше не будет
.each(function () {
console.log('each persistable input and select listeners (change, mouseout)');
const thisPersistable = $(this);
const Q12_or_Q23_is_not_empty = !commonUtility.isEmpty(Q12) &&
!commonUtility.isEmpty(Q23);
// Дополнительная логика...
...
});
}
return {
'changeCssClassIfOldAndNewValuesAreDifferent': changeCssClassIfOldAndNewValuesAreDifferent
};
})();
$(function(){
formController.changeCssClassIfOldAndNewValuesAreDifferent();
});
Теперь Q12
и Q23
инициализируются до того, как функция changeCssClassIfOldAndNewValuesAreDifferent
попытается их использовать. Это полностью устраняет проблему с ошибкой "Не удаётся обратиться к ‘Q12’ до инициализации".
Таким образом, разместив инициализацию переменных перед использованием, вы избежите возникновения ошибок, связанных с областью видимости переменных.