Understanding AS3 getDefinitionByName (for all eval maniacs)
Sometimes you may want to create a new class or DisplayObject only starting from its name. This is where something like an eval function would come into play, but we have to manage it in a different way with AS3.
Look at this movie:
Circles are four different objects called symbol1, symbol2, symbol3 and symbol4 and this is the script:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package { import flash.display.Sprite; public class Main extends Sprite { public function Main() { var s1:symbol1=new symbol1(); addChild(s1); s1.x=95; s1.y=100; var s2:symbol2=new symbol2(); addChild(s2); s2.x=245; s2.y=100; var s3:symbol3=new symbol3(); addChild(s3); s3.x=395; s3.y=100; var s4:symbol4=new symbol4(); addChild(s4); s4.x=545; s4.y=100; } } } |
Obviously it’s a bit unoptimized, just think about if we had a thousand objects. That’s when getDefinitionByName comes into play. It returns a reference to the class object of the class specified by the name parameter.
This means the same script can be written this way:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package { import flash.display.Sprite; import flash.utils.* public class Main extends Sprite { public function Main() { var symbolName:String; var symbolClass:Class; var s:Sprite; for (var i:int=1; i<=4; i++) { symbolName="symbol"+i; symbolClass=getDefinitionByName(symbolName) as Class; s=new symbolClass(); addChild(s); s.x=95+150*(i-1); s.y=100; } } } } |
DisplayObjects names are passed as strings in getDefinitionByName method and created as generic classes that can be used anywhere in the movie.
If you want to see a real world example, cracks textures in my upcoming game have been made this way:

Starting from a random number I create the texture according to such number and the material name.
Something to keep in mind if you can’t use anything similar to eval.
They can be easily customized to meet the unique requirements of your project.





(13 votes, average: 4.77 out of 5)







This post has 13 comments
Pierre Chamberlain
Quote:
“”
May want to look into the D.eval API:
http://www.riaone.com/products/deval/index.html
It provides a SWC you can add to your project in order to simulate the same behavior as eval(…).
Good tip on using getDefinitionByName though! It may be important to mark somewhere in your article how this can be used in Child SWFs for looking up any embedded classes in the Parent SWF, instead of compiling them in the each individual Child SWFs (which would increase overall project filesize).
:)
Pierre Chamberlain
Quote:
“Something to keep in mind if you can’t use anything similar to eval.”
May want to look into the D.eval API:
http://www.riaone.com/products/deval/index.html
It provides a SWC you can add to your project in order to simulate the same behavior as eval(…).
Good tip on using getDefinitionByName though! It may be important to mark somewhere in your article how this can be used in Child SWFs for looking up any embedded classes in the Parent SWF, instead of compiling them in the each individual Child SWFs (which would increase overall project filesize).
:)
EDIT: Sorry about the double post, forgot to include what I was quoting on your article!
Izik Bachar
It true when you are in the same package
if the classes you want to “eval”
are placesd in a diffrent package you need first or
- do import for the package with “*” sign to import all the classes you want to eval
-you need to use registerClassAlias method
Niraj
thanks for the tutorial
if you want to do more than getDefinitionByName then consider using
lang and reflect packages of http://www.as3commons.org/
Jorge Dourado
Simple&clean explanation!
Great tip ;)
ViolentAJ
The getDefinitionByName method is a very useful. When I first started AS3 a couple of years ago, I was disappointed because I didn’t know how to port my old spawning methods from AS2 (which used the attachMovie that allowed us to use the linkage name from the library unlike addChild).
This is going to be helpful for a lot of developers moving from AS2 to AS3 game design.
Philippe
Might be worth explaining how to use that using Flex SDK and pure AS3 projects – beginners will be very confused that this doesn’t work because the classes won’t be compiled automatically (ie. no “Export in 1st frame” as in Flash Pro).
Yarden Refaeli
Don’t forget that eval is a bad practice usually. Eval is evil. Well, at least in the HTML JS world. Why not to use arrays?
Fred
Hi!
thx for the code, but why wont work with other classes?
package com
{
import flash.display.Sprite;
import flash.utils.getDefinitionByName;
public class DefinitionSample extends Sprite
{
public function DefinitionSample()
{
var ClassReference:Class = getDefinitionByName(“com.Template”) as Class;
}
}
}
// ReferenceError: Error #1065: Variable Template is not defined.
thx!
Fred
Jorge
Yeap! I agree with Fred. There is a lack on this article… how to use it with custom classes ? (and not just the ones from as3)
Is the solution the one that “Izik Bachar” stated ?
–
Jorge
Matz
Am new to as3 if someone got the solution to why fred codes not working it would be of a great help to me
jackie
Hi
i used this code,but it didn’t work and throw “Error #1065: Variable Head1 is not defined”
Head1 is the class linkage name i defined in flash,and i publish it as swc.then link to my flash builder 4.6 .could you tell me whats going on?
ThatCoderGuy
For those having trouble with getting the example to work, and to answer Fred’s question:
You are likely running into an issue where the class in question has no clue what you are talking about in your “getDefinitionByName” call. To use Fred’s provided code as an example:
package com
{
import flash.display.Sprite;
import flash.utils.getDefinitionByName;
import com.Template;
public class DefinitionSample extends Sprite
{
Template;
public function DefinitionSample()
{
var ClassReference:Class = getDefinitionByName(“com.Template”) as Class;
}
}
}
This should now work. The reason for this is because at the time of trying to retrieve the definition, the application did not know what Template was. By invoking it at the beginning of the class (or anywhere before getDefinitionByName) we are essentially letting DefinitionSample know that Template actually exists.
This issue arises because when ActionScript is compiled it automatically cleans up any references to classes that it thinks you don’t need, and since Fred wasn’t implicitly calling Template earlier, it was viewed as unneeded. This is a gotcha that has caught many off-guard including myself, and is generally regarded as a bug with AS3, though it does make a bit of sense.
I hope you found this helpful and that the example I provided works. I didn’t actually test compiling it and I am running of memory a bit here.