Parametri di funzione

ActionScript 3.0 introduce alcune funzionalità relative ai parametri di funzione che potrebbero sembrare inedite ai programmatori che iniziano a utilizzare questo linguaggio. Benché l'idea di passare i parametri mediante un valore o un riferimento risulti probabilmente familiare alla maggior parte dei programmatori, l'oggetto arguments e il parametro ... (rest) potrebbero invece rappresentare una novità.

Sezioni

Passaggio di argomenti mediante un valore o un riferimento
Valori predefiniti dei parametri
L'oggetto arguments
Il parametro ... (rest)

Passaggio di argomenti mediante un valore o un riferimento

In molti linguaggi di programmazione, è importante comprendere la distinzione che esiste tra passare gli argomenti mediante un valore oppure mediante un riferimento, poiché tale distinzione può influire su come viene progettato il codice.

Passare un argomento mediante un valore significa copiarne il valore in una variabile locale da utilizzare con la funzione. Al contrario, si specifica un argomento mediante un riferimento, viene passato solo un riferimento all'argomento e non il valore effettivo. Nel secondo caso non viene quindi creata una copia dell'argomento vero e proprio, bensì viene passato come argomento un riferimento alla variabile nel momento in cui l'argomento viene creato e assegnato a una variabile locale da utilizzare nella funzione. Poiché è un riferimento a una variabile esterna alla funzione, la variabile locale consente di modificare il valore della variabile originale.

In ActionScript 3.0, tutti gli argomento vengono passati mediante riferimento perché tutti i valori sono memorizzati come oggetti. Tuttavia, gli oggetti che appartengono ai tipi di dati di base (Boolean, Number, int, uint e String) prevedono l'uso di operatori speciali grazie ai quali possono comportarsi come se venissero passati mediante un valore. Ad esempio, il codice seguente crea una funzione denominata passPrimitives() che definisce due parametri chiamati xParam e yParam, entrambi del tipo int. Questi parametri sono simili a variabili locali dichiarate nel corpo della funzione passPrimitives(). Quando la funzione viene chiamata con gli argomenti xValue e yValue, i parametri xParam e yParam vengono inizializzati mediante riferimenti agli oggetti int rappresentati da xValue e yValue. Poiché gli argomenti appartengono a un tipo di base, si comportano come se fossero passati mediante valore. Benché xParam e yParam contengano inizialmente solo riferimenti agli oggetti xValue e yValue, qualunque modifica delle variabili all'interno del corpo della funzione genera nuove copie dei valori in memoria.

function passPrimitives(xParam:int, yParam:int):void
{
    xParam++;
    yParam++;
    trace(xParam, yParam);
}

var xValue:int = 10;
var yValue:int = 15;
trace(xValue, yValue);          // 10 15
passPrimitives(xValue, yValue); // 11 16
trace(xValue, yValue);          // 10 15

All'interno della funzione passPrimitives(), i valori di xParam e yParam vengono incrementati, tuttavia ciò non influisce sui valori di xValue e yValue, come mostra l'ultima istruzione trace. Lo stesso varrebbe anche nel caso in cui i parametri avessero gli stessi nomi delle variabili, xValue e yValue, perché i valori xValue e yValue all'interno della funzione farebbero riferimento a nuove posizioni di memoria, distinte dalle variabili omonime esterne alla funzione.

Tutti gli altri oggetti, ovvero gli oggetti che non appartengono ai tipi di dati primitivi, vengono sempre passati mediante riferimento, quindi con la possibilità di modificare il valore della variabile originale. Ad esempio, il codice seguente crea un oggetto denominato objVar con due proprietà, x e y. L'oggetto viene passato come argomento alla funzione passByRef(). Poiché non appartiene a un tipo di base, l'oggetto non viene semplicemente passato mediante un riferimento, ma rimane un riferimento. Ciò significa che le modifiche apportate ai parametri all'interno della funzione avranno effetto sulle proprietà dell'oggetto all'esterno della funzione.

function passByRef(objParam:Object):void
{
    objParam.x++;
    objParam.y++;
    trace(objParam.x, objParam.y);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar);         // 11 16
trace(objVar.x, objVar.y); // 11 16

Il parametro objParam fa riferimento allo stesso oggetto della variabile globale objVar. Come si può notare nelle istruzioni trace dell'esempio, le modifiche apportate alle proprietà x e y dell'oggetto objParam vengono applicate anche all'oggetto objVar.

Valori predefiniti dei parametri

In ActionScript 3.0 è stata introdotta la possibilità di dichiarare dei valori di parametro predefiniti per una funzione. Se in una chiamata a una funzione con parametri predefiniti viene omesso un parametro con valori predefiniti, viene utilizzato il valore specificato per quel parametro nella definizione della funzione. Tutti i parametri con valori predefiniti devono essere posizionati alla fine dell'elenco dei parametri. I valori assegnati come predefiniti devono essere costanti della fase di compilazione. L'esistenza di un valore predefinito per un parametro fa sì che quel parametro diventi un parametro opzionale, mentre un parametro privo di valore predefinito viene considerato un parametro obbligatorio.

Ad esempio, il codice seguente crea una funzione con tre parametri, due dei quali hanno valori predefiniti. Quando la funzione viene chiamata con un solo parametro, vengono utilizzati i valori predefiniti dei parametri.

function defaultValues(x:int, y:int = 3, z:int = 5):void
{
    trace(x, y, z);
}
defaultValues(1); // 1 3 5

L'oggetto arguments

Quando si passano dei parametri a una funzione, è possibile utilizzare l'oggetto arguments per accedere alle informazioni relative a tali parametri. Seguono alcune osservazioni importanti relative all'oggetto arguments:

NOTA

 

L'oggetto arguments non è disponibile se è presente un parametro denominato arguments oppure se si utilizza il parametro ... (rest).

ActionScript 3.0 consente di includere nelle chiamate di funzione più parametri di quelli definiti nella definizione della funzione; tuttavia, in modalità rigorosa viene generato un errore del compilatore se il numero di parametri è inferiore a quello dei parametri obbligatori. È possibile ricorrere alla funzionalità di array dell'oggetto arguments per accedere a qualunque parametro passato alla funzione, a prescindere che sia o meno definito nella definizione della funzione. L'esempio seguente utilizza l'array arguments con la proprietà arguments.length per tracciare tutti i parametri passati alla funzione traceArgArray():

function traceArgArray(x:int):void
{
    for (var i:uint = 0; i < arguments.length; i++)
    {
        trace(arguments[i]);
    }
}

traceArgArray(1, 2, 3);

// output:
// 1
// 2
// 3

La proprietà arguments.callee viene spesso utilizzata nelle funzioni anonime per creare la ricorsività e rendere il codice più flessibile. Se il nome di una funzione ricorsiva cambia durante il ciclo di sviluppo, non occorre modificare la chiamata ricorsiva nel corpo della funzione se si utilizza arguments.callee al posto del nome della funzione. Nell'espressione di funzione seguente, la proprietà arguments.callee viene utilizzata per abilitare la ricorsività:

var factorial:Function = function (x:uint)
{
    if(x == 0)
    {
        return 1;
    }
    else
    {
        return (x * arguments.callee(x - 1));
    }
}

trace(factorial(5)); // 120

Se si utilizza il parametro ... (rest) nella dichiarazione della funzione, l'oggetto arguments non è disponibile e per accedere ai parametri è necessario utilizzare i rispettivi nomi che sono stati dichiarati.

È inoltre importante evitare di utilizzare la stringa "arguments" come nome di parametro perché impedisce l'uso dell'oggetto arguments. Ad esempio, se la funzione traceArgArray() viene riscritta con l'aggiunta di un parametro arguments, i riferimenti a arguments nel corpo della funzione sono relativi al parametro anziché all'oggetto arguments. Il codice seguente non produce alcun output:

function traceArgArray(x:int, arguments:int):void
{
    for (var i:uint = 0; i < arguments.length; i++)
    {
        trace(arguments[i]);
    }
}

traceArgArray(1, 2, 3);

// Nessun output

Nelle versioni precedenti di ActionScript, l'oggetto arguments conteneva anche una proprietà denominata caller, che era un riferimento alla funzione che chiamava la funzione corrente. La proprietà caller non è presente in ActionScript 3.0, ma se occorre fare riferimento alla funzione chiamante, è possibile modificare quest'ultima in modo che passi un parametro supplementare contenente un riferimento a se stessa.

Il parametro ... (rest)

In ActionScript 3.0 è stata introdotta una nuova dichiarazione di parametro, il parametro ... (rest), che consente di specificare un parametro array che accetta qualunque numero di argomenti separati da virgole. Il parametro può avere qualsiasi nome che non corrisponda a una parola riservata e deve essere l'ultimo parametro specificato. L'uso di questo parametro rende indisponibile l'oggetto arguments. Anche se il parametro ... (rest) offre la stessa funzionalità dell'array arguments e della proprietà arguments.length, non fornisce invece una funzionalità simile a quella di arguments.callee. Prima di usare il parametro ... (rest), assicurarsi che non sia necessario utilizzare arguments.callee.

Il seguente esempio riscrive la funzione traceArgArray() utilizzando il parametro ... (rest) invece dell'oggetto arguments:

function traceArgArray(... args):void
{
    for (var i:uint = 0; i < args.length; i++)
    {
        trace(args[i]);
    }
}

traceArgArray(1, 2, 3);

// output:
// 1
// 2
// 3

Il parametro ... (rest) può anche essere utilizzato con altri parametri, a condizione che venga specificato per ultimo. L'esempio seguente modifica la funzione traceArgArray() in modo tale che il primo parametro, x, sia del tipo int, e il secondo utilizzi il parametro ... (rest). L'output ignora il primo valore perché il primo parametro non fa più parte dell'array creato dal parametro ... (rest).

function traceArgArray(x: int, ... args)
{
    for (var i:uint = 0; i < args.length; i++)
    {
        trace(args[i]);
    }
}

traceArgArray(1, 2, 3);

// output:
// 2
// 3

Flash CS3

 

Inviami un messaggio e-mail quando vengono aggiunti dei commenti a questa | Rapporto sui commenti

Pagina corrente: http://livedocs.adobe.com/flash/9.0_it/main/00000055.html