Foo = new Object(); // instantiate an object
Foo.X = 37;
Foo.Name = "I'm a Foo!";
There, I just created an unclassed object and added two pieces of member data to it. The language has a constant called undefined that can be used to see if a value has been set in the object. . .
trace(Foo.X); // prints 37 to the console
trace(Foo.Y); // prints undefined to the console
This also means that you can perform the unheard-of act of removing members from an object. . .
Foo.Name = undefined; // removes the Name string from the object.
Again, it's not nearly as all-encompassing as C++ objects, and being able to add members willy-nilly is probably a Lispesque overly-dynamic performance headache, but for small stuff like my games, it's downright convenient.
It's also quite nice for objects that may or may not contain certain members. I For example, a cell in Duck Tiles can contain one or more of the following:
A wall above
A wall to the left
In C++, I would need to have storage defined for every one of these items (be it a pointer or index or the object itself), leaving most of them NULL because most cells would contain at most one or two of these items. If I had a larger project and object-fat became a problem, I could make all of the bits derived from some kind of BoardObject class and have the Cell object contain some kind of dynamic storage for BoardObjects, and have the objects able to identify themselves via a polymorphic function or RTTI.
Again, the elegance is probably an illusion, as the dynamic allocation required to support such a model will wipe out any potential memory or performance advantages of the approach.
It does, however, make ad-hoc solutions quite simple. For example, I was wondering how I could identify a particular movie clip as a duck if it's clicked. Suddenly the blindingly-obvious solution dawned on me. . .
TheMovieClip.duck = true;
Then I just check the "duck" member in the click-handler and I'm done.