Как (это) работает в этом коде, JavaScript? - PullRequest
1 голос
/ 13 июня 2019

Я пытаюсь сделать простое приложение To Do в качестве назначения, в этом коде флажок создается при каждом нажатии кнопки, а счетчик отслеживает непроверенные флажки, поэтому я сделал простое выражение if-else.... если щелкнуть по полю, уменьшить счетчик без проверки и наоборот .. моя проблема с this, здесь код, который я считаю логичным, поскольку validate() уже является атрибутом флажка, который не должен проходить this

const aCheckbox = document.createElement("INPUT");
aCheckbox.setAttribute('type', 'checkbox');
aCheckbox.setAttribute('onclick', 'validate()');

function validate() {
    if(this.checked) {
        console.log('Checked');
    }
}

Приведенный выше код не работает, я попробовал следующий код, и он работает, разница в том, что this передается, когда validate() вызывается при первом коде thisвызывается в validate(), так почему первый код не работает, даже если функция вызывается внутри флажка?

const aCheckbox = document.createElement("INPUT");
aCheckbox.setAttribute('type', 'checkbox');
aCheckbox.setAttribute('onclick', 'validate(this)');

function validate(x){
    if(x.checked){
        console.log('Checked');
    }
}

Ответы [ 3 ]

2 голосов
/ 13 июня 2019

Ключевое слово JavaScript this относится к объекту, которому оно принадлежит.

Имеет различные значения в зависимости от того, где он используется:

В методе this относится к объекту-владельцу. В одиночку это относится к глобальному объекту.
В функции this относится к глобальному объекту.
В строгом режиме функции this не определено.
В событии this относится к элементу, который получил событие.
Методы типа call() и apply() могут ссылаться this на любой объект.

1 голос
/ 13 июня 2019

Я создал пример без необходимости использовать this. Это может быть полезно.

<div id="app"></div>
  <p>checked boxes: <span id="checkedBoxes">0</span></p>
  <script>
    const getCheckedAmount = () => {
      const checkedBoxes = document
        .querySelectorAll('input[type="checkbox"]:checked');

      const amountOfCheckedBoxes = Array
        .from(checkedBoxes).length;

      document
        .querySelector('#checkedBoxes')
        .innerHTML = amountOfCheckedBoxes;
    };

    const addCheckBoxes = () => {
      const todoApp = document.querySelector("#app");

      const checkboxes = [1, 2, 3, 4, 5]
        .map(
          number =>
            `<input type="checkbox" onclick="getCheckedAmount()">${number}</input>`
        )
        .join(" ");

        todoApp.innerHTML = `<div>${checkboxes}</div>`;
    };

    addCheckBoxes();
  </script>
1 голос
/ 13 июня 2019

Приведенный выше код не работает, потому что this - это объект window в вашем случае. Даже если вы вручную создали кнопку в HTML, то и внутри обработчика щелчков был бы объект window.

Простое правило: this будет владельцем контекста, из которого вызывается функция.

Ниже приведена небольшая демонстрация вышеприведенной гипотезы и правильный способ сделать это:

function vTest(){
    console.log("this is same as window", this==window);
}

// Correct way to attach click event handlers to new elements.
function validate(e){
    console.log("validating");
    if(e.target.checked)
        console.log('Checked');
}

window.addEventListener("load", function(){
  var aCheckbox = document.createElement("INPUT");
  aCheckbox.setAttribute('type', 'checkbox');
  aCheckbox.addEventListener('click', validate);
  document.body.append(aCheckbox);
});
<input type="checkbox" onclick="vTest()"></input><br>

`

...