Zasięg
zmiennej jest to obszar kodu, w którym do zmiennej można odwoływać się leksykalnie. Zmienna
globalna
to zmienna zdefiniowana we wszystkich obszarach kodu, natomiast zmienna
lokalna
to zmienna zdefiniowana tylko w jednej części kodu. W języku ActionScript 3.0 zmienne mają zawsze przypisany zasięg funkcji lub klasy, w której zostały zadeklarowane. Zmienna globalna to zmienna zdefiniowana poza definicją jakiejkolwiek funkcji lub klasy. Na przykład poniższy kod tworzy zmienną globalną
strGlobal
, ponieważ jest ona zadeklarowana poza jakąkolwiek funkcją. Przykład ilustruje fakt, że zmienna globalna jest dostępna zarówno wewnątrz definicji funkcji, jak i poza tą definicją.
var strGlobal:String = "Global";
function scopeTest()
{
trace(strGlobal); // Global
}
scopeTest();
trace(strGlobal); // Global
Zmienną lokalną deklaruje się wewnątrz definicji funkcji. Najmniejszym obszarem kodu, w jakim można zadeklarować zmienną lokalną, jest definicja funkcji. Zmienna lokalna zadeklarowana wewnątrz funkcji istnieje tylko w tej funkcji. Na przykład, jeśli zadeklarujemy zmienną o nazwie
str2
w funkcji o nazwie
localScope()
, zmienna ta nie będzie dostępna na zewnątrz funkcji.
function localScope()
{
var strLocal:String = "local";
}
localScope();
trace(strLocal); // error because strLocal is not defined globally
Jeśli nazwa zmiennej lokalnej jest identyczna z nazwą zadeklarowanej zmiennej globalnej, to w zasięgu zmiennej lokalnej deklaracja lokalna ukryje (przesłoni) definicję globalną. Zmienna globalna istnieje nadal na zewnątrz funkcji. Na przykład poniższy kod tworzy zmienną globalną typu string o nazwie
str1
, a następnie tworzy zmienną lokalną o tej samej nazwie wewnątrz funkcji
scopeTest()
. Instrukcja
trace
wewnątrz funkcji wyświetla lokalną wartość zmiennej, ale instrukcja
trace
poza funkcją wyświetla wartość zmiennej globalnej.
var str1:String = "Global";
function scopeTest ()
{
var str1:String = "Local";
trace(str1); // Local
}
scopeTest();
trace(str1); // Global
W języku ActionScript, inaczej niż w języku C++ i Java, zmienne nie mają zasięgu na poziomie bloku. Blok kodu jest to dowolna grupa instrukcji między otwierającym nawiasem sześciennym (
{
) a zamykającym nawiasem sześciennym (
}
). W niektórych językach programowania, takich jak C++ i Java, zmienne zadeklarowane wewnątrz bloku kodu nie są dostępne poza tym blokiem. To ograniczenie zasięgu nie istnieje w języku ActionScript. Zmienna zadeklarowana wewnątrz bloku kodu jest dostępna nie tylko w tym bloku, lecz także we wszystkich innych częściach funkcji, do której należy ten blok kodu. Na przykład poniższa funkcja zawiera zmienne zdefiniowane w różnych blokach. Wszystkie te zmienne są dostępne w całej funkcji.
function blockTest (testArray:Array)
{
var numElements:int = testArray.length;
if (numElements > 0)
{
var elemStr:String = "Element #";
for (var i:int = 0; i < numElements; i++)
{
var valueStr:String = i + ": " + testArray[i];
trace(elemStr + valueStr);
}
trace(elemStr, valueStr, i); // all still defined
}
trace(elemStr, valueStr, i); // all defined if numElements > 0
}
blockTest(["Earth", "Moon", "Sun"]);
Interesującą implikacją braku zasięgu na poziomie bloków jest możliwość odczytywania i przypisywania wartości zmiennej zanim zostanie ona zadeklarowana, pod warunkiem że deklaracja zmiennej znajduje się gdziekolwiek przed końcem funkcji. Wynika to z zastosowania w kompilatorze techniki niejawnego przenoszenia deklaracji na początek funkcji (ang.
hoisting
). Na przykład poniższy kod jest formalnie poprawny mimo że pierwsze wywołanie funkcji
trace()
ze zmienną
num
znajduje się przed deklaracją zmiennej
num
:
trace(num); // NaN
var num:Number = 10;
trace(num); // 10
Przenoszenie deklaracji na początek funkcji nie jest jednak równoznaczne z analogicznym przenoszeniem instrukcji przypisania. Wyjaśnia to, dlaczego pierwsze wywołanie
trace()
dla zmiennej
num
zwraca wartość
NaN
(nie liczba), czyli domyślną wartość zmiennych typu Number. A zatem możliwe jest przypisywanie zmiennym wartości zanim zmienne te zostaną zadeklarowane, co ilustruje poniższy przykład:
num = 5;
trace(num); // 5
var num:Number = 10;
trace(num); // 10