Search code examples
javascriptobject-literal

Calling a function in javascript object literal notation declaration


I'm trying to call a function within an object literal that I created, using the this keyword. But an error shows up saying this.doTheMove() is not a function:

window.onload = function(){

  var animBtn = document.getElementById('startAnim');

  animBtn.addEventListener('click', Animation.init, false);

}

var Animation = {
  init: function(){

     this.doTheMove(); // I'm calling the function here, but it gives an error.

  },
  doTheMove: function(){

    alert('Animation!');

  }
}

Why is there an error?


Solution

  • An explanation of what's happening. Pointy's answer is good but I want to explain it more generically. A very good research on this can be found here

    An event handler is just a callback. You pass it a function and an event to listen on. Interally all it will do is call that function.

    Animation.init is just a getter for that function. Think of it like this:

    var callback = Animation.init
    animBtn.addEventListener('click', callback, false);
    ...
    // internal browser event handler
    handler() {
       // internal handler does stuff
       ...
       // Oh click event happened. Let's call that callback
       callback();
    }
    

    So all you've done is passed in

    var callback = function(){
       this.doTheMove(); // I'm calling the function here, but it gives an error.
    }
    

    By default in javascript this === window. This will refer to the global object if it isn't set to something. The net effect is that window.doTheMove is called. And that function doesn't exist.

    In this case since callback is actaully called by an event handler the this object points at the DOM object that triggered the event so your calling node.doTheMove which still doesn't exist.

    What you wanted to do is wrap it with a reference to Animation.

    var callback = function() {
        Animation.init();
    }
    

    This is a function execution and it executes init on Animation. When you execute it on an object like that then internally this === Animation as you would expect.

    To sum up. The issue here is that Animation.init is just a reference to a function. It has no information about anything else like Pointy mentioned.