Wednesday, December 5, 2012

Choosing between statements and literals

As a general rule, use function statements unless specific circumstances call for the use of function literals. Function statements are not only less verbose than function literals, but also provide a more consistent experience between strict mode and standard mode.
Function statements are easier to read than assignment statements that contain function literals. Using function statements makes your code more concise and are less confusing than function literals, which require use of both var and function keywords.
Function statements provide a more consistent experience between the two compiler modes in that you can use dot syntax in both strict and standard mode to invoke a method declared using a function statement. This is not necessarily true for methods declared with a function literal. For example, the following code defines a class named Example with two methods:
methodLiteral(), which is declared with a function literal, and methodStatement(), which is declared with a function statement. In strict mode, you cannot use dot syntax to invoke the methodLiteral() method.
class Example {
     var methodLiteral = function() {}
     function methodStatement() {}
}
myExample.methodLiteral();       // Error in strict mode
myExample.methodStatement(); // Okay in strict and standard modes
The use of function literals is considered better suited to programming that focuses more on runtime, or dynamic, behavior. If you prefer to use strict mode, but also need to call a method declared with a function literal, you can use either of two techniques. First, you can call the method using square brackets ([]) instead of the dot (.) operator. The following method call succeeds in both strict mode and standard mode:
myExample["methodLiteral"]();
Second, you can declare the entire class as a dynamic class. Although this allows you to call the method using the dot operator, the downside is that you sacrifice some strict mode functionality for all instances of that class. For example, attempts to access an undefined property on an instance of a dynamic class are not caught at compile time.
There are some circumstances in which function literals are useful. One common usage of function literals is for functions that are used only once, then discarded. Another usage, albeit much less common, is for attaching a function to a prototype property. For more information, see “The prototype object”.

There are two subtle differences between function statements and function literals that you should take into account when choosing which type to use. The first difference is that function literals do not exist independently as objects with regard to memory management and garbage collection. In other words, when you assign a function literal to another object, such as an array element or an object property, you create the only reference to that function literal in your code. If the array or object to which your function literal is attached goes out of scope or is otherwise no longer available, you will no longer have access to the function literal. If the array or object is deleted, then the memory that the function literal uses will become eligible for garbage collection, which means that the memory is eligible to be reclaimed and reused for other purposes.

The following example shows that for a function literal, once the property to which the literal is assigned is deleted, the function is no longer available. The class Test is dynamic, which means that you can add a property named literal that holds a function literal. The literal() function can be called with the dot operator, but once the literal property is deleted, the function is no longer accessible.
dynamic class Test {}
var myTest:Test = new Test();
                                   // function literal
myTest.literal = function () {trace ("Function literal")};
myTest.literal();           // Output: Function literal
delete myTest.literal;
myTest.literal();           // error
If, on the other hand, the function is first defined with a function statement, it exists as its own object, and continues to exist even after you delete the property to which it is attached. The delete operator only works on properties of objects, so even a call to delete the function
stateFunc() itself does not work.
dynamic class Test {}
var myTest:Test = new Test();
                                          // function statement
function stateFunc() {trace ("Function statement")}
myTest.statement = stateFunc;
myTest.statement();            // Output: Function statement
delete myTest.statement;
delete stateFunc; // no effect
stateFunc();                      // Output: Function statement
myTest.statement();          // error

The second difference between function statements and function literals is that function statements exist throughout the scope in which they are defined, including statements that appear before the function statement. Function literals, by contrast, are defined only for subsequent statements. For example, the following code successfully calls the scopeTest() function before it is defined:
statementTest();               // Output: statementTest
function statementTest() {
     trace ("statementTest");
}
Function literals are not available before they are defined, so the following code results in a runtime error:
literalTest(); // Runtime error
var literalTest:Function = function () {
     trace ("literalTest");
}


Programming Actionscript 3. Powered by Blogger.