Как использовать свойства объекта внутри параметризованной функции?

#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:

Поскольку теперь у вас есть конструктор, обратные вызовы вызываются немедленно, и только после их вызова конструктор возвращается. Два замечания по этому поводу:

  1. Поскольку конструктор еще не вернулся во время обратного вызова, d переменная еще не получила значение. Так d что в обратном вызове будет undefined .

  2. Это нереально, так как на практике вы хотели бы вызвать только один из обратных вызовов и только тогда, когда пользователь нажал кнопку. В это время d будет определено.

Вы все еще можете решить эту проблему, передав явную ссылку на созданный объект. Вы могли бы, например, передать его как this объект:

Изменить:

 noClicked();
  

…для:

 noClicked.call(this);
  

А затем в вашем обратном вызове измените:

 console.log(d.No);
  

…для:

 console.log(this.No);
  

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

1. Я понял. Во время передачи его конструктору d даже не было и существует только после того, как конструктор создает объект (который является d). Мне удалось решить проблему каким-то другим способом, но я также очень ценю ваш ответ (вы научили меня чему-то, что меня долго беспокоило. Спасибо).