What is the scope of a variable in eScript/Browser Script?

It is considered best practice, that we should always declare our variables outside the try/catch block. It is also one of the main recommendations of the following Siebel support document.

Assigning Null to Variables [ID 508828.1]

This was the question that was asked by the customer in the above article:

"In order for a variable to be referenced inside of a finally block, is it required for the variable to be declared before the try block, or can it be declared within the try block without any risk of not having all of the null statements work properly."


And Siebel provided this answer:

"If a variable is declared in the try block, there is no way to use them in the catch or even in the finally blocks, so using them in
these other blocks will lead to have an execution error."


This is the example that was provided to support this claim.

function foo()
{
var var1;

try
{
var var2;
if(true)
{
var var3;

for(var index = 0; index < 2; index++)
{
// Accessible variables are var1, var2, var3 and index
}
// Accessible variables are var1, var2 and var3
}
// Accessible variables are var1 and var2
}
catch(e)
{
var var4;
// Accessible variables are var1 and var4
}
finally
{
// Accessible variable is var1
}
}

This article was written by a very knowlegable person. The quality of his answers on Support web, shows that he has quite an extraordinary understanding of scripting, so one does not naturally question this sort of authority, but something didnt add up.

eScript which is based on ECMA script, does not have block level scoping. This is very important, because it means that the above test case will never prove true. Dont take it from me, take it from the ECMA standard itself, here is the reference.

http://www.ecma-international.org/publications/standards/ecma-262.htm

"A Block does not define a new execution scope. Only Program and Function Declaration produce a new scope"


There are two exceptions to this rule.

"the scope chain of the execution context is affected only by with statements and catch clauses."

But lets put standards and theory aside, because Siebel can add its own flavour into to the mix, so lets actually test the damn thing.

Take the above script, and trace out variable var2 in the finally block, this should not work according to the Siebel recommendation, but it does.

function foo()
{
try {
var var2=2;
}
catch(e){
}
finally {
// Accessible variable is var1
TheApplication().Trace(var2);
}
}

The explanation for this is, is eScript like ECMA Script has function scope. Any variable declared inside the function is a local variable, and is available throughout the lifetime of the function.

The test was done with primitive and complex objects, and has been tested in IE 6 Javascript, Siebel 8.1.1.1 eScript ST Engine, and Siebel 7.8 T Engine.

This illustration does not invalidate the Siebel recommendation, but it does highlight the importance of understanding why we have to do things in a particular way, and what effect it has.

Declaring variables outside the try/catch blocks comes from solid tradition, behind programming languages such Java and C. And if you are starting out in ECMA Script and want to learn Java in future, then this is one less scripting habit you have to change.

The only caution i would give, is dont add complex initialization routines for your variables outside the try catch, because you do not have the safety if it fails. Initialize it before the try, and use it in the try/catch/finally body.


1 comment:

  1. Good Post Jason !!!
    Just to add.

    I like to highlight there are fundamental flaws(in the comments as well as the understanding) in the escript
    provided by Siebel TSE.

    Lets check the escript in the Metalink.
    Check my inline comments prefixed by geeksajan

    function foo()
    {
    var var1;

    try
    {
    var var2;
    if(true)
    {
    var var3;

    for(var index = 0; index < 2; index++)
    {
    // Accessible variables are var1, var2, var3 and index
    }
    // Accessible variables are var1, var2 and var3
    }
    // Accessible variables are var1 and var2

    // geeksajan: Even var3 and index can be accessed.

    }
    catch(e)
    {
    var var4;
    // Accessible variables are var1 and var4
    // geeksajan: Even var2,var3 and index can be accessed.

    }
    finally
    {
    // Accessible variable is var1
    //geeksajan: var1 can be accessed even if declared within try.
    //geeksajan: var2,var3,index can be accessed.
    //geeksajan: var4 is available if there is an error in the try block ie execution navigates thru catch.Else undefined.

    }
    }
    - geeksajan
    http://geeksajan.blogspot.com/

    ReplyDelete

Comments are open to all, please make it constructive.