3

I have some JavaScript code that works as it should. However, I'm finding it a bit difficult to explain why it actually works. I hope, someone can make it clear to me. I have an object that must respond to certain events, e.g. click events. Part of the object looks like this:

Maps.Marker = function (id, data, clickEvent) {
    this.id = id;
    this.data = data;
    this.clicked = clickEvent;
};

The object is rendered in a Google map, so when the object is clicked in the map, I want to bubble the event to the clickEvent. Part of that code looks like this:

if (marker.clicked) { // click handler defined
google.maps.event.addListener(m, "click", function () { 
        marker.clicked();
});
}

Please note I've left out a lot of code here for brevity and know that it looks wrong as pasted here. The important thing is that the marker.clicked() function is invoked inside the Google Map event listener.

So, when my marker object is instantiated, it looks something like this:

var objClicked = function () {
if (this.data != null) {...}
...
}
var obj = new Maps.Marker("1", { "some object data" }, objClicked);

What I do not understand totally is how the this.data actually works in the objClicked function (I can access "some object data". Can someone please explain it to me?

Sean Bright
  • 109,632
  • 17
  • 131
  • 138
user1632306
  • 167
  • 2
  • 10

2 Answers2

3

The reason lies in the way of the this keyword in javascript. When you assign a function to a property inside an object and you later call this function, marker.clicked(), the this inside the function is set to whatever is on the left side of the dot, which in this case is marker.

UPDATE

Here is a more thorough explanation: http://www.impressivewebs.com/javascript-this-different-contexts/

chrisbuchholz
  • 639
  • 7
  • 17
1

You invoke the function like this:

  marker.clicked();

Because the reference to the function comes from that "clicked" property of the object that "marker" refers to, that object is used for the this value in the function. That's just how JavaScript works.

Note that if you did something weird like this:

  var wrong = {};
  wrong.clicked = marker.clicked;
  wrong.clicked();

then your code would not work, because this would refer to that "wrong" object.

So, in general: if an object has a property, and the property value is a reference to a function, and you invoke that function via the reference, then this in the function will refer to that object. That binding happens on each individual function call; there's no permanent relationship between a function and an object. (You can get the effect of a permanent relationship with something like .bind().)

Pointy
  • 371,531
  • 55
  • 528
  • 584
  • Thank you for the fast response. You say that "that's just how JavaScript works". Could you add some specific terms for this like scope or...? Or maybe even a link explaining this feature? – user1632306 May 29 '13 at 19:41
  • @user1632306 it's not really "scope". [Here is the spec for how function calls work.](http://www.ecma-international.org/ecma-262/5.1/#sec-11.2.3) See that stuff in step 6 about setting *thisValue*? (The ECMA spec is hard to read and confusing, unfortunately.) – Pointy May 29 '13 at 19:45
  • Thank you - great answer. Just wanted to make sure that it didn't have something to do with closures, that I had missed. – user1632306 May 30 '13 at 18:24