Make your own free website on Tripod.com

Event handlers


The variables in function;

There are many variables in a function. Some come from arguments and some are created by "var", while others may not have scope specified. When that function is called, how does Flash know what those variables are ?

Most of the time, we call that function by script and it is easy to guess what the variables are from context contain before this call.

It would be more complicated when we are creating a function to event handler. We do not know when that function will be called. 

Many discussion here may be already discussed in the section "about var".


EXAMPLE 1:

_root.btn.onPress=function(){
    trace(myVar);
}
var myVar="modified";


Here we enabled a button press function. When the button is pressed, Flash will print the value of "myVar'; When we read the script, it is obviously that, at the time when onPress function is created, we still not know what "myVar" is; "myVar" is still undefined at that time.  For C programmer, it is weird. The compiler can not resolve what it is. However, in script language, it does not matter. Everything is accessed by "name" dynamically not through pointer.

When the button is pressed, a process is started. The script within the function block is executed. When the function process meet the script "trace(myVar);", it will try to find a variable whose name is "myVar".

To know the sequence of "searching priority" is important. 

It starts from the function process itself. Well, there is no variable declaration before the line "trace(myVar);". There is no "myVar" in the memory of this function process. 

Now, it goes up. This function object is created by an execution of this section. This session may be part of a frame script or may be a part of a function. If this session is part of a function call then it will search for a variable with name as "myVar" in this local memory; Is there such variable ? Yes, although "myVar" is undefined when the event handler is created, it is defined now with its value "modified" when the button get pressed. So, it trace out "modified". 

What if there is no such variable named "myVar" ? It will goes up to the timeline where the session is located. If this block is written in frame script of an MC, then it try to find MC.myVar. 

What if there is no such variable in MC ? It will search for the __proto__ chain, to find the variable "myVar" in its ancestors. 

If there is still no such variable, it search for _global field.

There are two wrong expectings:

It will not search such variable in _root.btn;  It is different from "this.myVar";

It will not seach for _root, when it failed in MC.


EXAMPLE 2:

myVar="original";
enableButton=function(){
    btn.onPress=function(){
        trace(myVar);
    }
}
enableButton();
var myVar="modified";

When the button is clicke, the output is "modified";

There is nothing particular in this example, if we understand the mechanism in Example 1. If you expect the output after we click btn is "original", then you need to read example 1 again.

When we call enableButton(), onPress function is created. At that time, the value of myVar is "original". However, the value of myVar is changed later. So, when the btn is clicked, the output will be "modified";


EXAMPLE 3:

enableButtons=function(){
    for(var k=0;k<5;k++){
        _root["btn"+k].onPress=function(){
            trace(k);
        }
    }
}
enableButtons();

No matter what button is clicked, the output is "5";

This is a bad code. We enabled the onpress function of those 5 buttons. Each button has its own onPress function. There are 5 function objects created by the enableButtons calling process. However, no matter what button we click, the output is always "5", not expected "0,1,2,3,4";

No mtter what button is clicked, the onPress function will search for a variable name as "k"; That variable is found in the calling process of enableButtons. A single call creates 5 functions. There is only one temporary "k" created and its value when we click the button is 5;


EXAMPLE 4:

enableButtons=function(){
    for(var k=0;k<5;k++){
        _root["btn"+k].onPress=function(){
            var i=k;
            trace(i);
        }
    }
    for(var k=0;k<100;k++){
        trace(k);
    }
}
enableButtons();

The output is always "100";

There is nothing paricular in this example. No matter what button is clicked, the output is "100"; If this is not your answer, then read example 3 again.

When the button is clicked, onPress function try to find the variable "k" and then put the value to a temporary variable "i". The mechanism is the same as example 3.


EXAMPLE 5:

enableButton=function(n){
    _root["btn"+n].onPress=function(){
         trace(n);
    }
}
for(var k=0;k<5;k++){
    enableButton(k);
}

This is a good script. Each button will output different number when clicked.

Here, the function enabledButton is called 5 times. Each call, the calling process create a "local" variable n to carry the parameter. Each n is carrying with different value. When button is clicked, its onPress function will try to search a variable named "n"; There is no "n" in the onPress function. So, it trace up to the calling process that created the onPress function. Then "n" is found in the local memory. However, different onPress is created by different call of enableButton so is different n. Thus, the output is different.


EXAMPLE 6:

enableButton=function(){
    _root["btn"+buttonID].onPress=function(){
        trace(buttonID);
    }
}
for(var k=0;k<5;k++){
    buttonID=k;
    enableButton();
}


No matter what button is clicked, the output is "4";

This is a bad code. Notice that, although the function "enableButton" is called 5 times, but there is no additional variables created in the local. The variable "buttonID" lies out of the enableButton function. When button is clicked, it will search for "buttonID". There is only one unique "buttonID" in this session. The buttonID is 4 at the end of session; So, no matter what button is clicked, the output print "4"; Note, not "5" either.


EXAMPLE 7:

enableButton=function(n){
    btnVar=_root["btn"+n];
    btnVar.id=n;
    btnVar.onPress=function(){
   
         trace(btnVar.id);
   
}
}
for(var k=0;k<5;k++){
    enableButton(k);
}

The output is always "4";

This is a bad coding. It create 5 onPress function. When the button is clicked, it will try to find what is "btnVar" to get the id; Well, it is right that each button has different id. But, what is btnVar ? When the first enableButton is called, the calling process create a new variable named "btnVar" in the timeline. The second, third, fourth and fifth call only change the value of btnVar in the timeline. It did not create a calling process variable. So, no matter what button is clicked, it trace out the id of _root.btn4;

How to fix it ?

Fix 1: Declare btnVar as "temporary" variable by "var btnVar". So, each calling of enableButton will create a unique variable "btnVAr" in the process. So, each button onPress will find its version of btnVar.

Fix 2: Write "trace(this.id);" instead of "btnVar.id"; Then there is no problem about what btnVar is. The button will trace out the id of itself.