E.S
E.S

Reputation: 101

How does (this) work in this code, javascript?

I'm trying to make a simple To Do app as an assignment, in this code a checkbox is created every time a button is clicked and a counter keeps track of unchecked checkboxes, so I made a simple if-else statement.. if the box is clicked decrease unchecked counter and vice versa.. my problem is with this, here the code that I feel it's logical because validate() is already an attribute of the checkbox it shouldn't have to pass this

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

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

The above code doesn't work, I tried the following code and it does work, the difference is that this is passed when validate() is invoked while the first code this is called in validate(), so why the first code isn't working even though the function is called within the checkbox?

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

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

Upvotes: 1

Views: 57

Answers (3)

Neskews
Neskews

Reputation: 824

I created an example without the need to use this. It may be helpful.

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

Upvotes: 1

Shubham Agrawal
Shubham Agrawal

Reputation: 182

The above code is not working because this is the window object in your case. Even if you manually created the button in HTML, then also, this inside the click handler would have been the window object.

A simple rule of thumb: this will be the owner of the context from where the function is being called.

Following is a small demo of the above hypothesis and the correct way to do 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>

`

Upvotes: 1

A_E
A_E

Reputation: 176

The JavaScript this keyword refers to the object it belongs to.

It has different values depending on where it is used:

In a method, this refers to the owner object. Alone, this refers to the global object.
In a function, this refers to the global object.
In a function, in strict mode, this is undefined.
In an event, this refers to the element that received the event.
Methods like call(), and apply() can refer this to any object.

Upvotes: 2

Related Questions