0

How can I refer the the object itself in an event callback defined within an object literal in JS/jQuery please?

I have researched various answers and articles, such as this question: How to access the correct `this` inside a callback? but only found myself more confused.

It makes sense that this should refer to the element that was clicked as we need access to it, but how then do I refer the the object containing the binding function itself?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>This</title>
    <script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
</head>
<body>

    <button id="test">Click Me</button>
    <script>

        $( document ).ready( function() {

            console.log(MyObj.introspect());
            MyObj.bindEvents();

        } );

        MyObj = {
            myProperty : 'a property',

            bindEvents : function(){
                $('#test').on('click', MyObj.introspect)
            },

            introspect : function(){
                console.log(this);
            }
        }
    </script>
</body>
</html>
Robin Andrews
  • 3,514
  • 11
  • 43
  • 111
  • In addition to T.J Crowder's existing answer, the more general case to transfer `this` to sub-event handlers/callbacks where `this` changes is to make a copy up front. eg `var self=this; $(xx).each(function() { if (this == self) ... }` (some ppl use `var that=this;`) – freedomn-m Aug 03 '18 at 10:00

1 Answers1

1

In your case, you'd use MyObj, just like you did in bindEvents, since it's a singleton:

MyObj = {
    myProperty : 'a property',

    bindEvents : function(){
        $('#test').on('click', MyObj.introspect)
    },

    introspect : function(){
        console.log(MyObj);
        // ---------^^^^^
    }
}

Side note: Your code is falling prey to what I call The Horror of Implicit Globals. Be sure to declare your variables (with var, or ES2015's let or const). In your case, you can make MyObj entirely private since you only need it in your own code, by moving it into the ready callback and declaring it:

$( document ).ready( function() {
    var MyObj = {                                    // Note the `var`
        myProperty : 'a property',

        bindEvents : function(){
            $('#test').on('click', MyObj.introspect)
        },

        introspect : function(){
            console.log(MyObj);
        }
    };                                               // Also added missing ; here

    console.log(MyObj.introspect());
    MyObj.bindEvents();
});
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks. I'm still confused though. When I add these 2 new lines to `introspect` in my original version : `this.myOtherProperty = 'another property'; console.log(this.myOtherProperty);` it seems like `this` has returned to meaning the object, not the element. – Robin Andrews Aug 03 '18 at 10:09
  • @Robin - Elements are objects, you can add properties to them (though in general it's best not to). When you add a property to a DOM element it's often called an "expando property" (I'm not sure why). – T.J. Crowder Aug 03 '18 at 10:35