简体   繁体   中英

'this' binding in Reusable Functions?

I have put together a small script as part of a larger quiz project and am struggling to understand why the this keyword is being set in the function before it is called. Here is my code:

$(document).ready(function ($) {

     function nextCard() {
         console.log('yes');
         $(this).closest('.card').hide();
         $(this).parent().next().show();
     }

    $("#start").on('click', function (e) {
        e.preventDefault();

        //First card to appear
        nextCard();
    });

    $("#next").on('click', function (e) {
        e.preventDefault();
        nextCard();
    });
});

Why would 'this' not be set to element #start for instance?

Within nextCard() , this will refer to the window as that's the default scope. Hence your DOM traversal methods most likely are not working as you expect them to.

Assuming you want this within the function to refer to the clicked #start or #next element, you could provide the reference of nextCard() to the event handler methods, like this:

$(function($) {
  function nextCard(e) {
    e.preventDefault();
    console.log('yes');
    $(this).closest('.card').hide();
    $(this).parent().next().show();
  }

  $("#start, #next").on('click', nextCard);
});

Why would 'this' not be set to element #start for instance?

Why would it be? It's not that it can sense what you want it to do.

Use Function#call to define what object this should point to during the call. If you don't explicitly define it, this will default to the global object ( Window in browsers).

$(document).ready(function ($) {

    function nextCard() {
        console.log('yes');
        $(this).closest('.card').hide();
        $(this).parent().next().show();
    }

    $("#start").on('click', function (e) {
        e.preventDefault();

        //First card to appear
        nextCard.call(this);
    });

    $("#next").on('click', function (e) {
        e.preventDefault();
        nextCard.call(this);
    });
});

Using someFunction.call(this); will effectively "transfer the current meaning" of this to the called function, or more technically, call someFunction in the context of whatever object this is referencing at the moment.

jQuery does something like the above automatically - it sets this for you to the proper DOM element when it calls event handlers. You can make use of the automatic this handling like @Rory McCrossan's answer shows – or you handle this yourself.

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