Function , method and this


Function is like an automatic vender machine. We insert coin and it drop the product. It may functions ike a food machine. we feed meat and it returns the meatball. We pass each elements as the parameters. After some calculation and processing, it returns the result. Programmer ususally name these function with prefix - "get";

Function getDistance(x,y){
    return Math.sqrt(x*x+y*y);
}


Here we feed x and y. The function does calculation and returns the result to me.

Not every "Action" needs return the results. When we need to adjust the TV volume, the result is change of its internal settings, make volume meter up, make sound louder. It might changed 10 more internal settings. There are "effects" but no "results" that can be returned out. Programmer ususally name these function with prefix - "set";

Lets take a advance to the above example codes:

Function setDistance(point){
    var x=point.x;
    var y=point.y;
    point.distance=Math.sqrt(x*x+y*y);
}

Here an object will be feed as parameter "point". The result is to change the setting of "distance" in that object. Nothing is returned out.

It is something like: we send our TV to the vender. The vender changes the volume of TV by screw driver. In fact, that function is a "method" of the vender. Our TV is passed in as parameter.

Now lets see a real method of TV itself.

PointA.setDistance=function(){
    var x=this.x;
    var y=this.y;
    this.distance=Math.sqrt(x*x+y*y);
}

Now, we see that there is no "parameters" in this method. So what will be changed ? 

This is something like a volume adjuster knob in the TV set.  It is different from the screw driver of the vender. It functions by itself. The source and result are located in the object itself.

Object oriented programming loves these things. We like a TV equipped with full functions. We dont like a TV that needs to be sent to some vender for adjusting its volume. 


object2.setD=PointA.setDistance;

Method in OOP is design to handle internal properties, and is called by the object itself. The "variables" are internal properties instead of something outside which passed in through parameters.

Here is a problem. I have an object with x and y property and I need to calculate the distance. I can easily pass the reference as the parameter to a "fucntion" to get the result. Now, how about the method ?  I know, PointA has a method that can calculate the distance. But, if I say "PointA.setDistance();" , all it does is to calculate the distance of PointA itself. How do I use it ?

We get to make it as a method of my object. So,

object2.setD=PointA.setDistance;
object2.setD();

Now, our object2 is calling its method. So, "this" will be our object. That method will handle all the internal properties of our object2 not PointA object.


To define methods of an object in the method of other object:

Mc.onRelease=function(){
    this.clicked=true;
    ball1.onEnterFrame=function(){
        this._x+=3;
    }
}

The codes above is very common. It defines the method "onRelease" of a movieClip "Mc". Inside the method body, it defines a method "onEnterFrame" of a movieClip "ball1". The first "this" appears in the method of Mc, so it represent the movieClip "Mc". The second "this", appears in the method of ball1, so "this" represent the movieClip "ball1";


So, what is "this" ? 

When we say this.x, Whose x is it ?   When that is a method, it is an object calling its method. "this" is that object.

However, there are several points we should know:

1. What is "this" is decided dynamically.  It is the object that calls this method.

Method can only be called by the object itself. There is no syntax that makes an object calling the method of other object. At best, we can create a method that serves similar function as the method in other object. Then object calls this method.

We may try to call a function in _root. However, we should consider this process is " _root call its method" not an object calling the function of other object. In this condition, the changes and the result is to the _root, not my object. "this" represent the _root.

See paragraph above to know how to borrow a method of another object to be the method of my object.

It is TV2 that is adjusting the volume. It is silly if we press volume adjuster of my TV  just to set the volume of your TV. So, what is "this" is determined dynamically. It depends on which object is executing this method.

2. What is "this" if it appear in a function not a method ? In fact, a function is also a method.

Well, we see "this" in the body of many function definition. The function definition may be in the frame script or onClipEvent. Then what is "this" when it is a function ? 

Theoretically, "this" points to nothing if it is a function. It only make sense when it is called as a method so we know who is the owner. We need to know what object is executing this method.

However, MovieClip itself is an Object. When we declare a function in the timeline of that movieClip, it is a method of that movieClip. In this condition, "this" means that movieClip.

function move(){this._x+=5;}
move();


This is treated as 

thisClip.move=function(){this._x+=5;}
thisClip.move();

3. "this" in constructor and method.

When this function is called with new, then "this" represent the new created instance not the timeline.

Point=functon(){
    this.name="me";
}
Point.name="him";

Lets clarify several condtions:

Point(); 

Here, thisClip is calling a method "Point". We get "this" to be thisClip. The result is to set thisClip.name as "me";

p1=new Point();

Here, we get "new". So, it is treated as constructor. We get "this" to be the new created instance : p1. The result is p1.name="me";

So, whose name is "him" ? It is the name of that function. 

fun=Point; 
trace(fun.name);// output: "him";

constr=p1.__constructor__;
trace(constr.name);// output: "him";

4. Is "this" read only ?

We should let flash decide what is "this". Do not do assignment.

We should treat "this" as read only. We can trace what is "this". But don't assign any object to be "this".. 

When I begin to learn OOP, I tried a codes to do inheritance and  that does not work:

//Not work codes:

subClass=function(){
    this=new superClass();
    this.x=5;
}

obj1=new subClass();

Here it just treat "this" as a custom variable name. It does not possess the meaning of what we know about "this". Of course, that script fails.