Method binding As a consequence of this being "passed" to functions, this is not fixed for a function. That means that a function does not have an "owner" or "parent", even if it is a method. In other words, a method is not bound to the object that it is a method of.
A more general explanation of the underline problem of my last post. Essentially, what object the keyword this references inside of a function can change, based "who" is calling the function.
//constructor for new Car object
function Car(name) {
this.name = name;
}
//method for object
function Car_display() {
alert(this.name);
}
//adds the method display() to all car objects
Car.prototype.display = Car_display;
//creates a new Car object
var car = new Car("Vette");
car.display(); //prints out "Vette" as expected
//creates a new Car object
var car2 = new Car("Truck");
car2.display(); //prints out "Truck" as expected
//grab a reference to the car function
var carfunc = car.display;
//set a global variable whose name is name
var name = "HAHAHA!";
carfunc(); //prints out "HAHAHA" WTF?
Car_display(); //prints out "HAHAHA" WTF?
Here is what's happening. When JavaScript executes the state car.display() it first finds the function pointed to by the variable car.display; That function is Car_display. JavaScript also sets the this variable to the object which called the function. In this case, that object was car which we created. Thus Car_display is executed and the this variable points to the object car which contains a member variable name. What about car2.display()? The same thing. JavaScript it first finds the function pointed to by the variable car2.display; That function is still Car_display. JavaScript also sets the this variable to the object which called the function. In this case, that object was car2. Thus Car_display is executed and this is pointing to the car2 variable, whose name variable is "Truck." There is a single function Car_display, and all instances of a car object simply call that function, and JavaScript sets up the "environment" so that is it accessing the proper variables. Nothing so far is too different than a OO language like C# or Java. Next we save a reference to the function car.display, which is really a reference to Car_display, in the variable carfunc When we execute the statement carfunc() are calling the function Car_display. But what is the value of this? Well, since the function was called in the global context, this references to the global object. All function and variables in the program are ultimately part of the global object. In this example the global object has the following variables: -Car: a function -Car_display: a function -car: a variable, currently an instance of a Car object -car2: a variable, currently an instance of a Car object -carfunc: a variable which references the function Car_display -name: a variable, currently set to the string "HAHAHA" So, carfunc() calls the function Car_display, and sets the variable this to point at the global object. Since this.name reference to the global object's variable name, the function displays "HAHAHA." A closure allows you to get around this weirdness. See the referenced article for more information |