简体   繁体   中英

How to use the “this” keyword when calling a function in an anonymous function in Javascript?

I am looking to call a function that was originally just an anonymous function, but it turned out I need this function 3 times in my code. So I defined a function like this:

 function saveButton() { this.parentElement.parentElement.querySelector('h3').innerHTML = this.parentElement.querySelector('input[name="task-title"]').value; this.parentElement.parentElement.querySelector('p').innerHTML = this.parentElement.querySelector('textarea').value; this.parentElement.parentElement.querySelector('.popup').className = 'popup hidden'; this.parentElement.parentElement.querySelector('.overlay').className = 'overlay hidden'; saveWork(); }; 

I want to call this function in an anonymous function like this :

 confirmButton.onclick = function() saveButton(); }; 

But afterwards I realized that I couldn't use the this in the anonymous function. How can I call confirmButton() in the anonymous function?

confirmButton.onclick = saveButton;

or

confirmButton.onclick = function(){
    saveButton.call(this);
};

although it's not a good practice to have the same name for DOM node and a function that you want to call. rename your function into something that makes more sense like buttonClick

Have you tried using function expressions? Essentially it means assigning a function to a variable. Read this answer to learn about the differences between function expressions and function declarations.

As for your question, most of the time it's this case:

You want to use the parent scope of a given anonymous function.

If thats the case, I would recommend this neat little trick:

var self = this;

this.saveButton = function() { // or self.saveButton...
  this.parentElement.parentElement.querySelector('h3').innerHTML = this.parentElement.querySelector('input[name="task-title"]').value;
  this.parentElement.parentElement.querySelector('p').innerHTML = this.parentElement.querySelector('textarea').value;
  this.parentElement.parentElement.querySelector('.popup').className = 'popup hidden';
  this.parentElement.parentElement.querySelector('.overlay').className = 'overlay hidden';
  saveWork();
};

confirmButton.onclick = function() {
    self.saveButton();
}

This trick can be used in any level of scope depth, just don't pollute the global namespace :)

By looking at the code fragment you posted, and guessing a few things, I suggest the following refactoring:

function saveButton(parentElem) {
  var myParent = parentElem || this.parentElement;
  myParent.parentElement.querySelector('h3').innerHTML = myParent.querySelector('input[name="task-title"]').value;
  myParent.parentElement.querySelector('p').innerHTML = myParent.querySelector('textarea').value;
  myParent.parentElement.querySelector('.popup').className = 'popup hidden';
  myParent.parentElement.querySelector('.overlay').className = 'overlay hidden';
  saveWork();
}

confirmButton.onclick = function() {
  // I suppose when this function is called somewhere else,
  // you actually know who is the parent element, so:
  saveButton(document.querySelector('.theParentElement'));
};

// If you calling it somewhere where "this" is available,
// then simply call the function with no arguments:
saveButton();

Maybe some variation of the example above can help you. Other than that, I can't think of a better answer without looking at a greater portion of your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM