#javascript #object #undefined #javascript-objects
#javascript #объект #не определено #javascript-объекты
Вопрос:
Я работал над диалогом в проекте и превратил его в конструктор объектов.
function createDialog(title, noClicked = function(){}, yesClicked = function(){}) {
this.dialog = document.getElementsByClassName("dialog")[0];
this.dialogTitle = this.dialog.getElementsByTagName("h1")[0];
this.No = this.dialog.getElementsByTagName("button")[0];
this.Yes = this.dialog.getElementsByTagName("button")[1];
var dialog = document.getElementsByClassName("dialog")[0];
this.dialogTitle.innerHTML = title;
document.getElementsByClassName("dialogCon")[0].style.display = "flex";
noClicked();
yesClicked();
}
<div class="dialogCon">
<div class="dialog">
<h1></h1>
<button type="button">No</button>
<button type="button">Yes</button>
</div>
</div>
Проблема в том, что когда я хочу получить доступ «this.no » или «this.yes» Я продолжаю получать Не удается прочитать свойство «No» неопределенного значения. Это произошло, когда я использовал приведенный ниже код:
var d = new createDialog("Sample dialog. Exit?", function() {
console.log(d.No);
}, function() {
console.log(d.Yes);
});
Мне нужно использовать d.Нет, чтобы закрыть диалоговое окно. Есть ли другой способ сделать это? Или, по крайней мере, исправление.
Я осознаю тот факт, что я мог бы закрыть диалоговое окно из самого конструктора, но я хочу, чтобы можно было делать и другие вещи (например, определять, выбирает ли пользователь «да» или «нет»).
Заранее спасибо
Комментарии:
1. Проблема в том, что вы вызываете
noClicked
иyesClicked
внутри метода. Это предшествует моменту, когда экземпляр был создан и назначен обратноd
, поэтому он все равно будет неопределенным.
Ответ №1:
Вы вызываете noClicked() и yesClicked() непосредственно внутри конструктора. Я думаю, вы хотели бы вызвать их по нажатию кнопок «Нет» и «Да«. Вам нужно добавить эти функции в прослушиватели событий кнопок. Попробуйте приведенный ниже фрагмент.
function createDialog(title, noClicked = function(){}, yesClicked = function(){}) {
this.dialog = document.getElementsByClassName("dialog")[0];
this.dialogTitle = this.dialog.getElementsByTagName("h1")[0];
this.No = this.dialog.getElementsByTagName("button")[0];
this.Yes = this.dialog.getElementsByTagName("button")[1];
var dialog = document.getElementsByClassName("dialog")[0];
this.dialogTitle.innerHTML = title;
document.getElementsByClassName("dialogCon")[0].style.display = "flex";
this.No.addEventListener('click',noClicked);
this.Yes.addEventListener('click',yesClicked);
}
var d = new createDialog("Sample dialog. Exit?", function() {
console.log(d.No);
}, function() {
console.log(d.Yes);
});
<div class="dialogCon">
<div class="dialog">
<h1></h1>
<button type="button">No</button>
<button type="button">Yes</button>
</div>
</div>
Комментарии:
1. Спасибо! Это решило мою проблему. Это была глупая ошибка tbh. Я думал о добавлении EventListeners после определения каждого объекта диалога (т.Е. Я должен время от времени делать больше перерывов).
Ответ №2:
Поскольку теперь у вас есть конструктор, обратные вызовы вызываются немедленно, и только после их вызова конструктор возвращается. Два замечания по этому поводу:
-
Поскольку конструктор еще не вернулся во время обратного вызова,
d
переменная еще не получила значение. Такd
что в обратном вызове будетundefined
. -
Это нереально, так как на практике вы хотели бы вызвать только один из обратных вызовов и только тогда, когда пользователь нажал кнопку. В это время
d
будет определено.
Вы все еще можете решить эту проблему, передав явную ссылку на созданный объект. Вы могли бы, например, передать его как this
объект:
Изменить:
noClicked();
…для:
noClicked.call(this);
А затем в вашем обратном вызове измените:
console.log(d.No);
…для:
console.log(this.No);
Комментарии:
1. Я понял. Во время передачи его конструктору d даже не было и существует только после того, как конструктор создает объект (который является d). Мне удалось решить проблему каким-то другим способом, но я также очень ценю ваш ответ (вы научили меня чему-то, что меня долго беспокоило. Спасибо).