Gegevenstypen
Een gegevenstype definieert een set waarden. Het gegevenstype Boolean is bijvoorbeeld de set met precies twee waarden: true en false. Naast het gegevenstype Boolean zijn in ActionScript 3.0 diverse gangbare gegevenstypen gedefinieerd, zoals String, Number en Array. U kunt uw eigen gegevenstypen definiëren door met behulp van klassen of interfaces een aangepaste set waarden te definiëren. Alle waarden in ActionScript 3.0, primitieve en complexe, zijn objecten.
Een primitieve waarde behoort tot een van de volgende gegevenstypen: Boolean, int, Number, String en uint. Het werken met primitieve waarden is doorgaans sneller dan het werken met complexe waarden, omdat in ActionScript primitieve waarden op een speciale manier worden opgeslagen, waarbij geheugen en snelheid worden geoptimaliseerd.
Opmerking: Voor lezers met belangstelling voor de technische details: in ActionScript worden primitieve waarden intern opgeslagen als onveranderlijke objecten. Dit betekent dat het doorgeven als verwijzing hetzelfde effect heeft als doorgeven als waarde. Zo wordt het geheugengebruik minder en de snelheid van uitvoering hoger, omdat verwijzingen meestal aanzienlijk kleiner zijn dan de waarden zelf.
Een complexe waarde is een waarde die geen primitieve waarde is. Gegevenstypen die sets complexe waarden definiëren, zijn Array, Date, Error, Function, RegExp, XML en XMLList.
In veel programmeertalen wordt onderscheid gemaakt tussen primitieve waarden en de bijbehorende omvattende objecten. Java heeft bijvoorbeeld een primitieve int en de klasse java.lang.Integer die deze omvat. Primitieven in Java zijn geen objecten, maar de omvattende objecten wel. Dit maakt primitieven handig voor sommige bewerkingen en omvattende objecten beter geschikt voor andere bewerkingen. In ActionScript 3.0 wordt uit praktische overwegingen geen onderscheid gemaakt tussen primitieve waarden en de omvattende objecten. Alle waarden, dus ook primitieve waarden, zijn objecten. Tijdens de uitvoering worden deze primitieve typen als speciale gevallen behandeld die zich als objecten gedragen, maar niet de normale overhead vereisen die gepaard gaat met het maken van objecten. Dit betekent dat de volgende twee regels code gelijkwaardig zijn:
var someInt:int = 3;
var someInt:int = new int(3);
Alle genoemde primitieve en complexe gegevenstypen worden gedefinieerd door de kernklassen van ActionScript 3.0. Met behulp van de kernklassen kunt u objecten maken en letterlijke waarden gebruiken in plaats van de operator new te gebruiken. U kunt bijvoorbeeld als volgt een array maken met een letterlijke waarde of de klassenconstructor Array:
var someArray:Array = [1, 2, 3]; // literal value
var someArray:Array = new Array(1,2,3); // Array constructor
Type controlerenHet type kan worden gecontroleerd bij compilatie of uitvoering. In statisch getypeerde talen, zoals C++ en Java, wordt het type gecontroleerd bij compilatie. In dynamisch getypeerde talen, zoals Smalltalk en Python, wordt het type gecontroleerd bij uitvoering. ActionScript 3.0 is een dynamisch getypeerde taal en controle van het type vindt dus bij uitvoering plaats. Controle van het type bij compilatie wordt echter ook ondersteund in een speciale compilermodus, strikte modus genoemd. In de strikte modus vindt controle van het type bij zowel compilatie als uitvoering plaats, in de standaardmodus alleen bij uitvoering.
Dynamisch getypeerde talen bieden een grote mate van flexibiliteit wanneer u code structureert. Daardoor kunnen bij uitvoering echter wel typeringsfouten optreden. Statisch getypeerde talen rapporteren typeringsfouten bij compilatie, maar dan moet de type-informatie bij compilatie al wel bekend zijn.
Type controleren bij compilatieType controleren bij compilatie geniet vaak de voorkeur bij grotere projecten. Flexibiliteit in de gegevenstypen is bij grotere projecten immers vaak van minder belang dan het zo vroeg mogelijk afvangen van typefouten. Daarom wordt de ActionScript-compiler in Flash Professional en Flash Builder standaard uitgevoerd in de strikte modus.
Adobe Flash BuilderU kunt de strikte modus in Flash Builder uitschakelen via de compileerinstellingen voor ActionScript in het dialoogvenster Project Properties (Projecteigenschappen).
Voor het controleren van het type bij compilatie moet in de compiler de informatie over gegevenstypen bekend zijn voor de variabelen of expressies in de code. U kunt een gegevenstype expliciet declareren voor een variabele door de operator dubbelepunt (:) toe te voegen, gevolgd door het gegevenstype als achtervoegsel van de variabelenaam. U kunt een gegevenstype aan een parameter koppelen door de operator dubbelepunt te gebruiken, gevolgd door het gegevenstype. Met de volgende code wordt bijvoorbeeld informatie over het gegevenstype toegevoegd aan de parameter xParam en wordt een variabele myParam gedeclareerd met een expliciet gegevenstype:
function runtimeTest(xParam:String)
{
trace(xParam);
}
var myParam:String = "hello";
runtimeTest(myParam);
In de strikte modus rapporteert de ActionScript-compiler niet-overeenkomende typen als compilatiefouten. Met de volgende code wordt bijvoorbeeld een functieparameter xParam gedeclareerd van het type Object. Verderop wordt geprobeerd waarden van het type String en Number toe te voegen aan die parameter. Dit resulteert in een compilatiefout in de strikte modus.
function dynamicTest(xParam:Object)
{
if (xParam is String)
{
var myStr:String = xParam; // compiler error in strict mode
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam; // compiler error in strict mode
trace("Number: " + myNum);
}
}
Zelfs in de strikte modus kunt u controle van het type bij compilatie selectief omzeilen door de rechterkant van een toewijzingsinstructie zonder type te laten. U kunt een variabele of expressie zonder type markeren door een typeannotatie weg te laten of door de speciale asterisk (*) te gebruiken als typeannotatie. Als de parameter xParam in het vorige voorbeeld geen typeannotatie krijgt, wordt de code als volgt in de strikte modus gecompileerd:
function dynamicTest(xParam)
{
if (xParam is String)
{
var myStr:String = xParam;
trace("String: " + myStr);
}
else if (xParam is Number)
{
var myNum:Number = xParam;
trace("Number: " + myNum);
}
}
dynamicTest(100)
dynamicTest("one hundred");
Type controleren bij uitvoeringType controleren bij uitvoering vindt altijd plaats in ActionScript 3.0, of u nu compileert in de strikte modus of in de standaardmodus. Neem bijvoorbeeld een situatie waarin de waarde 3 als argument wordt doorgegeven aan een functie die een array verwacht. In de strikte modus wordt een compilatiefout gegenereerd, omdat de waarde 3 niet compatibel is met het gegevenstype Array. Als u de strikte modus uitschakelt en in de standaardmodus werkt, worden bij compilatie de niet-overeenkomende typen niet als fout gemeld. Bij controle van het type bij uitvoering treedt echter wel een uitvoeringsfout op.
In het volgende voorbeeld wordt een functie getoond met de naam typeTest() die een argument van het type Array verwacht, maar de waarde 3 krijgt doorgegeven. Dit resulteert in een uitvoeringsfout in de standaardmodus, omdat de waarde 3 geen lid is van het gedeclareerde gegevenstype voor de parameter (Array).
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum:Number = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0 standard mode
Er kunnen zich ook situaties voordoen waarin een uitvoeringsfout optreedt zelfs terwijl u in de strikte modus werkt. Dit is mogelijk wanneer u de strikte modus gebruikt, maar controle van het type bij compilatie omzeilt door een variabele zonder type te gebruiken. Wanneer u een variabele zonder type gebruikt, wordt het controleren van het type niet uitgeschakeld, maar uitgesteld tot uitvoering plaatsvindt. Als bijvoorbeeld de variabele myNum in het vorige voorbeeld geen gedeclareerd gegevenstype heeft, worden de niet-overeenkomende typen niet gedetecteerd in de compiler. De code genereert echter een uitvoeringsfout, omdat de uitvoeringswaarde van myNum, die op 3 is ingesteld door de toewijzingsinstructie, wordt vergeleken met het type van xParam, die is ingesteld op het gegevenstype Array.
function typeTest(xParam:Array)
{
trace(xParam);
}
var myNum = 3;
typeTest(myNum);
// run-time error in ActionScript 3.0
Controle van het type bij uitvoering biedt tevens meer flexibiliteit voor het gebruik van overerving dan controle bij compilatie. Door de controle van het type uit te stellen tot de uitvoering, kunt u in de standaardmodus naar eigenschappen van een subklasse verwijzen zelfs wanneer er sprake is van upcasting. Een upcast treedt op wanneer u een basisklasse gebruikt om het type van een klasseninstantie te declareren, maar een subklasse om deze te instantiëren. U kunt bijvoorbeeld een klasse maken met de naam ClassBase die kan worden uitgebreid (klassen met het attribuut final kunnen niet worden uitgebreid):
class ClassBase
{
}
Vervolgens kunt u als volgt een subklasse van ClassBase maken met de naam ClassExtender, die één eigenschap heeft met de naam someString:
class ClassExtender extends ClassBase
{
var someString:String;
}
Met behulp van beide klassen kunt u een klasseninstantie maken die is gedeclareerd met het gegevenstype ClassBase, maar geïnstantieerd met de constructor ClassExtender. Een upcast wordt als een veilige bewerking beschouwd, omdat de basisklasse geen eigenschappen of methoden bevat die zich niet in de subklasse bevinden.
var myClass:ClassBase = new ClassExtender();
Een subklasse bevat echter eigenschappen of methoden die de basisklasse niet heeft. De klasse ClassExtender bevat bijvoorbeeld de eigenschap someString, die niet bestaat in de klasse ClassBase. In de standaardmodus van ActionScript 3.0 kunt u naar deze eigenschap verwijzen met de instantie myClass zonder een compilatiefout te genereren, zoals in het volgende voorbeeld wordt getoond:
var myClass:ClassBase = new ClassExtender();
myClass.someString = "hello";
// no error in ActionScript 3.0 standard mode
De operator isMet de operator is kunt u testen of een variabele of expressie lid is van een bepaald gegevenstype. In eerdere versies van ActionScript vervulde de operator instanceof deze rol. In ActionScript 3.0 moet u de operator instanceof echter niet gebruiken om lidmaatschap van gegevenstypen te testen. U gebruikt de operator is in plaats van de operator instanceof om het type handmatig te controleren, omdat de expressie x instanceof y alleen maar de prototypeketen van x controleert op het bestaan van y (en in ActionScript 3.0 geeft de prototypeketen geen volledig beeld van de overervingshiërarchie).
De operator is controleert de juiste overervingshiërarchie. U kunt daarmee niet alleen controleren of een object een instantie is van een bepaalde klasse, maar ook of een object een instantie is van een klasse die een bepaalde interface implementeert. In het volgende voorbeeld wordt een instantie gemaakt van de klasse Sprite met de naam mySprite en wordt met de operator is getest of mySprite een instantie is van de klassen Sprite en DisplayObject en of implementatie van de interface IEventDispatcher plaatsvindt:
var mySprite:Sprite = new Sprite();
trace(mySprite is Sprite); // true
trace(mySprite is DisplayObject);// true
trace(mySprite is IEventDispatcher); // true
De operator is controleert de overervingshiërarchie en rapporteert correct dat mySprite compatibel is met de klassen Sprite en DisplayObject (de klasse Sprite is een subklasse van de klasse DisplayObject). De operator is controleert ook of mySprite overerft van enige andere klassen die de interface IEventDispatcher implementeren. Omdat de klasse Sprite overerft van de klasse EventDispatcher, die de interface IEventDispatcher implementeert, rapporteert de operator is correct dat mySprite dezelfde interface implementeert.
In het volgende voorbeeld worden dezelfde tests als in het vorige voorbeeld getoond, maar nu met de operator instanceof in plaats van is. De operator instanceof stelt correct vast dat mySprite een instantie is van Sprite of DisplayObject, maar retourneert false bij het testen of mySprite de interface IEventDispatcher implementeert.
trace(mySprite instanceof Sprite); // true
trace(mySprite instanceof DisplayObject);// true
trace(mySprite instanceof IEventDispatcher); // false
De operator asMet de operator as kunt u ook controleren of een expressie lid is van een bepaald gegevenstype. Anders dan bij de operator is, retourneert de operator as echter geen Booleaanse waarde. De operator as retourneert de waarde van de expressie in plaats van true en null in plaats van false. In het volgende voorbeeld worden de resultaten getoond van het gebruik van de operator as in plaats van de operator is. Het betreft een eenvoudige controle of een instantie van Sprite lid is van de gegevenstypen DisplayObject, IEventDispatcher en Number.
var mySprite:Sprite = new Sprite();
trace(mySprite as Sprite); // [object Sprite]
trace(mySprite as DisplayObject); // [object Sprite]
trace(mySprite as IEventDispatcher); // [object Sprite]
trace(mySprite as Number); // null
Wanneer u de operator as gebruikt, moet de operand aan de rechterkant een gegevenstype zijn. Een poging om aan de rechterkant een andere expressie dan een gegevenstype te gebruiken als operand, resulteert in een fout.
Dynamische klassenEen dynamische klasse definieert een object dat bij uitvoering kan worden gewijzigd door eigenschappen en methoden toe te voegen of te wijzigen. Een klasse die niet dynamisch is, zoals de klasse String, is een verzegelde klasse. U kunt bij uitvoering geen eigenschappen of methoden toevoegen aan een verzegelde klasse.
U maakt dynamische klassen door het attribuut dynamic te gebruiken wanneer u een klasse declareert. Met de volgende code wordt bijvoorbeeld een dynamische klasse gemaakt met de naam Protean:
dynamic class Protean
{
private var privateGreeting:String = "hi";
public var publicGreeting:String = "hello";
function Protean()
{
trace("Protean instance created");
}
}
Als u later een instantie van de klasse Protean instantieert, kunt u er eigenschappen of methoden aan toevoegen buiten de klassendefinitie. Met de volgende code wordt bijvoorbeeld een instantie gemaakt van de klasse Protean en wordt aan de instantie een eigenschap toegevoegd met de naam aString en een eigenschap met de naam aNumber:
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
trace(myProtean.aString, myProtean.aNumber); // testing 3
Eigenschappen die u toevoegt aan een instantie van een dynamische klasse zijn uitvoeringsentiteiten, zodat de controle van het type bij uitvoering plaatsvindt. U kunt geen typeannotatie toevoegen aan een eigenschap die u op deze manier toevoegt.
U kunt ook een methode toevoegen aan de instantie myProtean door een functie te definiëren en de functie te koppelen aan een eigenschap van de instantie myProtean. Met de volgende code wordt de instructie trace verplaatst naar een methode met de naam traceProtean():
var myProtean:Protean = new Protean();
myProtean.aString = "testing";
myProtean.aNumber = 3;
myProtean.traceProtean = function ()
{
trace(this.aString, this.aNumber);
};
myProtean.traceProtean(); // testing 3
Methoden die u op deze manier maakt, hebben echter geen toegang tot eigenschappen of methoden van de klasse Protean van het type private. Bovendien moeten zelfs verwijzingen naar eigenschappen en methoden van de klasse Protean van het type public worden gekwalificeerd met het trefwoord this of met de klassennaam. In het volgende voorbeeld wordt getoond hoe de methode traceProtean() probeert toegang te krijgen tot variabelen van de klasse Protean van het type private en public.
myProtean.traceProtean = function ()
{
trace(myProtean.privateGreeting); // undefined
trace(myProtean.publicGreeting); // hello
};
myProtean.traceProtean();
Beschrijving van gegevenstypenDe primitieve gegevenstypen zijn Boolean, int, Null, Number, String, uint en void. De kernklassen van ActionScript definiëren ook de volgende complexe gegevenstypen: Object, Array, Date, Error, Function, RegExp, XML en XMLList.
Boolean, gegevenstypeHet gegevenstype Boolean bestaat uit twee waarden: true en false. Voor variabelen van het type Boolean zijn geen andere waarden geldig. De standaardwaarde van een Booleaanse variabele die is gedeclareerd maar niet is geïnitialiseerd, is false.
int, gegevenstypeHet gegevenstype int wordt intern opgeslagen als een 32-bits geheel getal en bestaat uit de set gehele getallen van
-2,147,483,648 (-231) tot en met 2.147.483.647 (231 - 1). Eerdere versies van ActionScript kenden alleen het gegevenstype Number, voor zowel gehele getallen als getallen met drijvende komma. In ActionScript 3.0 hebt u nu toegang tot machinetypen op laag niveau voor 32-bits gehele getallen met en zonder teken. Als de variabele geen getallen met drijvende komma nodig heeft, is het gebruik van het gegevenstype int in plaats van het gegevenstype Number sneller en efficiënter.
Voor waarden van gehele getallen buiten het bereik van de minimale en maximale waarde voor int gebruikt u het gegevenstype Number. Daarmee zijn waarden mogelijk tussen positief en negatief 9.007.199.254.740.992 (53-bits gehele getallen). De standaardwaarde voor variabelen van het gegevenstype int is 0.
Null, gegevenstypeHet gegevenstype Null bevat maar één waarde: null. Dit is de standaardwaarde voor het gegevenstype String en alle klassen die complexe gegevenstypen definiëren, waaronder de klasse Object. Geen van de andere primitieve gegevenstypen, zoals Boolean, Number, int en uint, bevat de waarde null. Tijdens de uitvoering wordt de waarde null omgezet in de toepasselijke standaardwaarde wanneer u null probeert toe te wijzen aan variabelen van het type Boolean, Nummer, int of uint. U kunt dit gegevenstype niet als typeannotatie gebruiken.
Number, gegevenstypeIn ActionScript 3.0 kan het gegevenstype Number gehele getallen, gehele getallen zonder teken en getallen met drijvende komma vertegenwoordigen. Voor maximale prestaties dient u het gegevenstype Number echter alleen te gebruiken voor gehele getallen met waarden groter dan de 32-bits typen int en uint kunnen opslaan, of voor getallen met drijvende komma. Als u een getal met drijvende komma wilt opslaan, moet u een decimaal teken opnemen in het getal. Als u het decimale teken weglaat, wordt het getal opgeslagen als een geheel getal.
Het gegevenstype Number gebruikt de 64-bits indeling met dubbele precisie zoals is gespecificeerd in de standaard IEEE-754 (voor berekeningen met binaire getallen met drijvende komma). Deze standaard schrijft voor hoe getallen met drijvende komma worden opgeslagen met behulp van de 64 beschikbare bits. Eén bit wordt gebruikt om aan te duiden of het getal positief of negatief is. Elf bits worden gebruikt voor de exponent, die wordt opgeslagen als grondtal 2. De resterende 52 bits worden gebruikt voor de opslag van de significant (ook wel mantisse genoemd). Dit is het getal dat tot de macht wordt verheven die de exponent aangeeft.
Door sommige bits voor de opslag van een exponent te gebruiken kan het gegevenstype Number getallen met drijvende komma opslaan die aanzienlijk hoger zijn dan wanneer alle bits voor de significant zouden worden gebruikt. Als het gegevenstype Number bijvoorbeeld alle 64 bits zou gebruiken voor de opslag van de significant, kan het een getal opslaan van maximaal 265 - 1. Door 11 bits te gebruiken voor de opslag van een exponent, kan het gegevenstype Number de significant verheffen tot de macht 21023.
De maximale en minimale waarde die het gegevenstype Number kan vertegenwoordigen, wordt opgeslagen in statische eigenschappen van de klasse Number met de naam Number.MAX_VALUE en Number.MIN_VALUE.
Number.MAX_VALUE == 1.79769313486231e+308
Number.MIN_VALUE == 4.940656458412467e-324
Hoewel dit bereik van getallen enorm is, gaat dit ten koste van de precisie. Het gegevenstype Number gebruikt 52 bits voor de opslag van de significant. Dit heeft tot gevolg dat getallen waarvoor meer dan 52 bits nodig zijn voor een exacte representatie, zoals de breuk 1/3, slechts benaderingen zijn. Als voor uw toepassing absolute precisie is vereist voor decimale getallen, moet u software gebruiken die berekeningen met decimale getallen met drijvende komma implementeert in tegenstelling tot berekeningen met binaire getallen met drijvende komma.
Wanneer u waarden van gehele getallen opslaat met het gegevenstype Number, worden alleen de 52 bits van de significant gebruikt. Het gegevenstype Number gebruikt deze 52 bits en een speciale verborgen bit om gehele getallen te vertegenwoordigen van -9.007.199.254.740.992 (-253) tot 9.007.199.254.740.992 (253).
De waarde NaN wordt niet alleen gebruikt als de standaardwaarde voor variabelen van het type Number, maar ook als het resultaat van een bewerking die een getal moet retourneren maar dat niet doet. Als u bijvoorbeeld probeert de vierkantswortel van een negatief getal te berekenen, is het resultaat NaN. Andere speciale waarden voor Number zijn positief oneindig en negatief oneindig.
Opmerking: Het resultaat van delen door 0 is alleen NaN als de deler ook 0 is. Delen door 0 resulteert in oneindig wanneer het deeltal positief is of in -oneindig wanneer het deeltal negatief is.
String, gegevenstypeHet gegevenstype String vertegenwoordigt een reeks van 16-bits tekens. Tekenreeksen worden intern opgeslagen als Unicode-tekens in de UTF-16-indeling. Tekenreeksen zijn, net als in de programmeertaal Java, onveranderlijk. Een bewerking op een tekenreekswaarde retourneert een nieuwe instantie van de tekenreeks. De standaardwaarde voor een variabele die met het gegevenstype String wordt gedeclareerd, is null. De waarde null is niet hetzelfde als de lege string (""). De waarde null betekent dat er in de variabele geen waarde is opgeslagen, terwijl de lege string betekent dat de variabele een waarde bevat, die bestaat uit een String zonder tekens.
uint, gegevenstypeHet gegevenstype uint wordt intern opgeslagen als een 32-bits geheel getal zonder teken en bestaat uit de set gehele getallen van 0 tot en met 4.294.967.295 (232 - 1). Gebruik het gegevenstype uint in speciale situaties waarbij niet-negatieve gehele getallen nodig zijn. U moet het gegevenstype uint bijvoorbeeld gebruiken om pixelkleurwaarden te vertegenwoordigen. Het gegevenstype int heeft namelijk een interne tekenbit die niet geschikt is voor de verwerking van kleurwaarden. Voor waarden van gehele getallen boven de maximale waarde voor uint gebruikt u het gegevenstype Number. Daarmee zijn waarden mogelijk van 53-bits gehele getallen. De standaardwaarde voor variabelen van het gegevenstype uint is 0.
void, gegevenstypeHet gegevenstype void bevat maar één waarde: undefined. In eerdere versies van ActionScript was undefined de standaardwaarde voor instanties van de klasse Object. In ActionScript 3.0 is de standaardwaarde voor instanties van Object null. Wanneer u probeert de waarde undefined toe te wijzen aan een instantie van de klasse Object, wordt de waarde omgezet in null. U kunt alleen een waarde undefined toewijzen aan variabelen zonder type. Variabelen zonder type zijn variabelen zonder typeannotatie of met het asterisksymbool (*) als typeannotatie. U kunt void alleen gebruiken als retourneringstypeannotatie.
Object, gegevenstypeHet gegevenstype Object wordt gedefinieerd door de klasse Object. De klasse Object dient als basisklasse voor alle klassendefinities in ActionScript. De versie van het gegevenstype Object in ActionScript 3.0 verschilt op drie manieren van eerdere versies. Ten eerste is het gegevenstype Object niet meer het standaardgegevenstype dat wordt toegewezen aan variabelen zonder typeannotatie. Ten tweede omvat het gegevenstype Object niet meer de waarde undefined, die de standaardwaarde was voor instanties van Object. Ten derde is in ActionScript 3.0 de standaardwaarde voor instanties van de klasse Object null.
In eerdere versies van ActionScript werd aan een variabele zonder typeannotatie automatisch het gegevenstype Object toegewezen. Dit is niet meer het geval in ActionScript 3.0, waarin nu werkelijk variabelen zonder type voorkomen. Variabelen zonder typeannotatie worden nu als variabelen zonder type beschouwd. Als u aan lezers van de code duidelijk wilt maken dat u een variabele opzettelijk zonder type hebt gelaten, kunt u het asterisksymbool (*) gebruiken als typeannotatie. Dit staat gelijk aan het weglaten van een typeannotatie. In het volgende voorbeeld worden twee gelijkwaardige instructies getoond, waarbij in beide gevallen een variabele zonder type x wordt gedeclareerd:
var x
var x:*
Alleen variabelen zonder type kunnen de waarde undefined bevatten. Wanneer u probeert de waarde undefined toe te wijzen aan een variabele met een gegevenstype, wordt tijdens de uitvoering de waarde undefined omgezet in de standaardwaarde voor dat gegevenstype. Voor instanties van het gegevenstype Object, is de standaardwaarde null, wat betekent dat als u probeert om undefined aan een Objectinstantie toe te wijzen, de waarde wordt omgezet in null.
TypeomzettingenEen typeomzetting vindt plaats wanneer een waarde wordt omgezet in een waarde van een ander gegevenstype. Typeomzettingen kunnen impliciet of expliciet zijn. Impliciete omzetting, wat ook wel afgedwongen wordt genoemd, wordt soms tijdens de uitvoering uitgevoerd. Als de waarde 2 bijvoorbeeld wordt toegewezen aan een variabele van het gegevenstype Boolean, wordt de waarde 2 omgezet in de Booleaanse waarde true voordat de waarde aan de variabele wordt toegewezen. Expliciete omzetting, ook wel casting genoemd, treedt op wanneer de code de compiler opdraagt een variabele van een bepaald gegevenstype te behandelen alsof deze tot een ander gegevenstype behoort. In het geval van primitieve waarden worden met casting waarden van het ene gegevenstype daadwerkelijk in een ander type omgezet. Wanneer u een object wilt casten naar een ander type, plaatst u het object tussen ronde haakjes en laat u deze voorafgaan door de naam van het nieuwe type. De volgende code neemt bijvoorbeeld een Booleaanse waarde en cast deze naar een geheel getal:
var myBoolean:Boolean = true;
var myINT:int = int(myBoolean);
trace(myINT); // 1
Impliciete omzettingenImpliciete omzettingen treden bij uitvoering op in een aantal contexten:
In toewijzingsinstructies
Wanneer waarden worden doorgegeven als functieargumenten
Wanneer waarden worden geretourneerd uit functies
In expressies met bepaalde operatoren, zoals de operator voor optellen (+)
Voor door de gebruiker gedefinieerde typen zijn impliciete omzettingen mogelijk wanneer de om te zetten waarde een instantie is van de doelklasse of van een klasse die van de doelklasse is afgeleid. Als een impliciete omzetting mislukt, treedt een fout op. De volgende code bevat bijvoorbeeld een geslaagde impliciete omzetting en een mislukte impliciete omzetting:
class A {}
class B extends A {}
var objA:A = new A();
var objB:B = new B();
var arr:Array = new Array();
objA = objB; // Conversion succeeds.
objB = arr; // Conversion fails.
Voor primitieve typen worden impliciete omzettingen afgehandeld door dezelfde interne omzettingsalgoritmen aan te roepen als voor expliciete omzettingsfuncties.
Expliciete omzettingenHet toepassen van expliciete omzettingen, of casting, is nuttig wanneer u in de strikte modus compileert en bijvoorbeeld wilt voorkomen dat niet-overeenkomende typen in compilatiefouten resulteren. Dit kan het geval zijn wanneer u weet dat door afgedwongen omzetting de waarden bij uitvoering correct worden omgezet. Wanneer u bijvoorbeeld werkt met gegevens die afkomstig zijn uit een formulier, kunt u door afgedwongen omzetting ervoor zorgen dat bepaalde tekenreekswaarden worden omgezet in numerieke waarden. Met de volgende code wordt een compilatiefout gegenereerd, ook al zou de code in de standaardmodus correct worden uitgevoerd:
var quantityField:String = "3";
var quantity:int = quantityField; // compile time error in strict mode
Als u verder wilt werken in de strikte modus maar de tekenreeks wilt omzetten in een geheel getal, kunt u als volgt expliciete omzetting toepassen:
var quantityField:String = "3";
var quantity:int = int(quantityField); // Explicit conversion succeeds.
Casting naar int, uint en NumberU kunt elk gegevenstype casten naar een van de drie getaltypen: int, uint en Number. Als het getal om een bepaalde reden niet kan worden omgezet, wordt de standaardwaarde 0 voor de gegevenstypen int en uint toegewezen en wordt de standaardwaarde van NaN voor het gegevenstype Nummer toegewezen. Als u een Booleaanse waarde omzet in een getal, wordt true de waarde 1 en false de waarde 0.
var myBoolean:Boolean = true;
var myUINT:uint = uint(myBoolean);
var myINT:int = int(myBoolean);
var myNum:Number = Number(myBoolean);
trace(myUINT, myINT, myNum); // 1 1 1
myBoolean = false;
myUINT = uint(myBoolean);
myINT = int(myBoolean);
myNum = Number(myBoolean);
trace(myUINT, myINT, myNum); // 0 0 0
Tekenreekswaarden met alleen cijfers kunnen in een van de getaltypen worden omgezet. De getaltypen kunnen ook tekenreeksen omzetten die eruitzien als negatieve getallen of tekenreeksen die een hexadecimale waarde vertegenwoordigen (bijvoorbeeld 0x1A). Bij het omzettingsproces worden voorafgaande en navolgende witruimtetekens in de tekenreekswaarde genegeerd. U kunt ook tekenreeksen casten die eruitzien als getallen met drijvende komma door Number() te gebruiken. Het opnemen van een decimaal teken zorgt ervoor dat uint() en int() een geheel getal retourneren met de tekens achter het decimale teken ingekort. De volgende tekenreekswaarden kunnen bijvoorbeeld naar getallen worden gecast.
trace(uint("5")); // 5
trace(uint("-5")); // 4294967291. It wraps around from MAX_VALUE
trace(uint(" 27 ")); // 27
trace(uint("3.7")); // 3
trace(int("3.7")); // 3
trace(int("0x1A")); // 26
trace(Number("3.7")); // 3.7
Tekenreekswaarden met niet-numerieke tekens retourneren 0 bij het casten met int() of uint(), en NaN bij het casten met Number(). Bij het omzettingsproces worden voorafgaande en navolgende witruimtetekens genegeerd, maar wordt 0 of NaN geretourneerd als een tekenreeks witruimte bevat die twee getallen van elkaar scheidt.
trace(uint("5a")); // 0
trace(uint("ten")); // 0
trace(uint("17 63")); // 0
In ActionScript 3.0 ondersteunt de functie Number() geen octale getallen (met grondtal 8). Als u een tekenreeks met een voorloopnul gebruikt voor de functie Number() in ActionScript 2.0, wordt het getal als octaal getal geïnterpreteerd en omgezet in het decimale equivalent ervan. Dat geldt niet voor de functie Number() in ActionScript 3.0, waarbij de voorloopnul wordt genegeerd. Met de volgende code wordt bijvoorbeeld verschillende uitvoer gegenereerd bij het compileren met verschillende versies van ActionScript:
trace(Number("044"));
// ActionScript 3.0 44
// ActionScript 2.0 36
Casting is niet nodig wanneer een waarde van een numeriek type wordt toegewezen aan een variabele van een ander numeriek type. Zelfs in de strikte modus wordt het numerieke type impliciet omgezet in het andere numerieke type. Dit kan in sommige gevallen resulteren in onverwachte waarden wanneer het bereik van een type wordt overschreden. De volgende voorbeelden worden allemaal gecompileerd in de strikte modus, hoewel bij sommige onverwachte waarden worden gegenereerd:
var myUInt:uint = -3; // Assign int/Number value to uint variable
trace(myUInt); // 4294967293
var myNum:Number = sampleUINT; // Assign int/uint value to Number variable
trace(myNum) // 4294967293
var myInt:int = uint.MAX_VALUE + 1; // Assign Number value to uint variable
trace(myInt); // 0
myInt = int.MAX_VALUE + 1; // Assign uint/Number value to int variable
trace(myInt); // -2147483648
In de volgende tabel wordt een overzicht gegeven van de resultaten van casting naar het gegevenstype Number, int of uint van andere gegevenstypen.
Gegevenstype of waarde
|
Resultaat van omzetting in Number, int of uint
|
Boolean
|
Als de waarde true is, 1; anders 0.
|
Date
|
De interne representatie van het object Date, ofwel het aantal milliseconden dat is verstreken sinds middernacht op 1 januari 1970, universele tijd.
|
null
|
0
|
Object
|
Als de instantie null is en omgezet in Number, NaN; anders 0.
|
Tekenreeks
|
Een getal als de string in een getal kan worden omgezet en anders NaN als het in een Number wordt omgezet of 0 als het wordt omgezet in int of uint.
|
undefined
|
Bij omzetting in Number, NaN; bij omzetting in int of uint, 0.
|
Casting naar BooleanCasting naar Boolean van een numeriek gegevenstype (uint, int en Number) resulteert in false als de numerieke waarde 0 is, anders in true. Voor het gegevenstype Number resulteert de waarde NaN ook in false. In het volgende voorbeeld wordt het resultaat getoond van het casten van de getallen -1, 0 en 1:
var myNum:Number;
for (myNum = -1; myNum<2; myNum++)
{
trace("Boolean(" + myNum +") is " + Boolean(myNum));
}
De uitvoer in het voorbeeld laat zien dat van de drie getallen alleen 0 de waarde false retourneert:
Boolean(-1) is true
Boolean(0) is false
Boolean(1) is true
Casting naar Boolean van een tekenreekswaarde retourneert false als de tekenreeks null is of leeg is (""). Anders wordt true geretourneerd.
var str1:String; // Uninitialized string is null.
trace(Boolean(str1)); // false
var str2:String = ""; // empty string
trace(Boolean(str2)); // false
var str3:String = " "; // white space only
trace(Boolean(str3)); // true
Casting naar Boolean van een instantie van de klasse Object retourneert false als de instantie null is; anders true:
var myObj:Object; // Uninitialized object is null.
trace(Boolean(myObj)); // false
myObj = new Object(); // instantiate
trace(Boolean(myObj)); // true
Variabelen van het type Boolean worden in de strikte modus speciaal behandeld. U kunt namelijk zonder casting waarden van elk gegevenstype toewijzen aan een variabele van het type Boolean. Impliciete afgedwongen omzetting van alle gegevenstypen in het gegevenstype Boolean gebeurt zelfs in de strikte modus. Met andere woorden, casting naar Boolean is, anders dan bij bijna alle andere gegevenstypen, niet nodig om fouten in de strikte modus te voorkomen. De volgende voorbeelden worden allemaal gecompileerd in de strikte modus en het gedrag bij uitvoering is zoals wordt verwacht:
var myObj:Object = new Object(); // instantiate
var bool:Boolean = myObj;
trace(bool); // true
bool = "random string";
trace(bool); // true
bool = new Array();
trace(bool); // true
bool = NaN;
trace(bool); // false
In de volgende tabel wordt een overzicht gegeven van de resultaten van casting naar het gegevenstype Boolean van andere gegevenstypen:
Gegevenstype of waarde
|
Resultaat van omzetting in Boolean
|
Tekenreeks
|
false als de waarde null of een lege tekenreeks ("") is; anders true.
|
null
|
false
|
Number, int of uint
|
false als de waarde NaN of 0 is; anders true.
|
Object
|
false als de instantie null is; anders true.
|
Casting naar StringCasting naar het gegevenstype String van een numeriek gegevenstype retourneert een tekenreeksrepresentatie van het getal. Casting naar het gegevenstype String van een Booleaanse waarde retourneert de tekenreeks 'true' als de waarde true is en retourneert de tekenreeks 'false' als de waarde false is.
Casting naar het gegevenstype String van een instantie van de klasse Object retourneert de tekenreeks 'null' als de instantie null is. Anders wordt bij het casten naar het gegevenstype String van een instantie van de klasse Object de tekenreeks '[object Object]' geretourneerd.
Casting naar String van een instantie van de klasse Array retourneert een tekenreeks die bestaat uit een door komma's gescheiden lijst met alle arrayelementen. Bij het casten naar het gegevenstype String wordt in het volgende voorbeeld één tekenreeks geretourneerd met de drie elementen van de array:
var myArray:Array = ["primary", "secondary", "tertiary"];
trace(String(myArray)); // primary,secondary,tertiary
Casting naar String van een instantie van de klasse Date retourneert een tekenreeksrepresentatie van de datum die de instantie bevat. In het volgende voorbeeld wordt een tekenreeksrepresentatie geretourneerd van een instantie van de klasse Date:
var myDate:Date = new Date(2005,6,1);
trace(String(myDate)); // Fri Jul 1 00:00:00 GMT-0700 2005
In de volgende tabel wordt een overzicht gegeven van de resultaten van casting naar het gegevenstype String van andere gegevenstypen.
Gegevenstype of waarde
|
Resultaat van omzetting in String
|
Array
|
Een tekenreeks die bestaat uit alle arrayelementen.
|
Boolean
|
"true" of "false"
|
Date
|
Een tekenreeksrepresentatie van het object Date.
|
null
|
"null"
|
Number, int of uint
|
Een tekenreeksrepresentatie van het getal.
|
Object
|
Als de instantie null is 'null'; anders '[object Object]'.
|
|
|