|
-
Terrible Flash for each problem
Can someone explain to me why Flash would ever do this with a for each
Code:
//Create a prototype function on an object
Object.prototype.hello = function() {
trace("Hello World");
}
//Create a simple object
var bob:Object = {Name:"Bob", Age:"50"}
//Iterate over the object
for each(var thing in bob) {
trace(thing + " is " + typeof thing);
}
Here is the output for the above piece of code:
Bob is string
50 is number
function Function() {} is function
Look carefully at that. Look at the bob object: it only has TWO values, a string and a number. But the output amazingly shows that bob has THREE values. And the last value is...an empty fuction! How could this be?
Flash thinks that the PROTOTYPE method is a variable in Object! It took me forever to track this down. I was about to go insane. It doesn't just happen for object, oh no. If you do a foreach on ANY class (dictionary, XMLList, what have you) with a prototype method, Flash screws up and thinks the prototype method is actually just a variable in the object, even though it only outputs a blank function.
So this is a bug in Flash, right? A prototype method shouldn't show up when looping through the object. By that logic, ALL methods of the object should show up in a for each. Does anyone have any suggestions for a workaround, or a better way to loop through Objects? I'll be here, growing my hair back.
-
I'm not up on my prototypes, but arent you essentially saying that all Objects inherently have a property 'hello'? Why are you surprised that your object then iterates over it when you look through it's members? Observe:
PHP Code:
Object.prototype.hello = function() {}
var bob:Object = {Name:"Bob", Age:"50"}
for (var thing in bob){
trace(thing + ' => ' + bob[thing]);
}
// Age => 50
// Name => Bob
// hello => function Function() {}
-
With that logic, the foreach should also trace methods like toString, hasOwnProperty, etc.
-
I think the difference is that those are native...I'm just guessing tho, someone out here must have a good link on this stuff?
-
I don't think native is the issue. In ECMAScript all objects have certain methods because those methods are prototypes of the objects. Adding a prototype method to an object type should make it appear as native, not a property of the object that you can iterate over.
-
Right but it's still a dynamic property (as you added it at runtime...) which is what the for-in loops iterate. To resolve that problem, I think you'd need to custom class it and make that function private or protected.
Again, I'm right at the edge of my AS3 knowledge but this is a really interesting thread - anyone more knowledgeable want to weigh in?
-
Neznein9 is completely right, according to my understanding.
According to the livedocs, for..in does iterate over the dynamic properties only. In AS3, there are three ways that an object can get properties, in general: The old AS2/javascript prototype way, directly adding a dynamic property at runtime, and native (class-based). The first two are considered dynamic, the third is not.
I bet that if you added a goodbye property to the prototype and gave it a function value, that you'd see TWO "extras" in the for..in loop. This indicates that it is iterating over these two new dynamic properties, and not counting the prototype as a property itself, as was asserted earlier. prototype is also not a method, which I think was just a poor choice of words. It's a native property with special semantics.
-
Well, it looks like you guys maybe right. I just tried this code in JavaScript and it had the same outcome. Here's the code if anyone's interested:
PHP Code:
Object.prototype.hello = function(str){
alert(str);
}
var obj = {Prop1:"asdf", Prop2:"jkl;"}
//obj.hello("hi");
for(thing in obj) {
alert(thing +":"+ obj[thing])
}
It doesn't seem like it would be in my best interest to wrap all classes that I need prototype methods into other classes. I don't want to write a framework over the XML class. The solution I've come up with for now is just the obvious one, which is to just make them public methods, non prototype.
function hello = new function(obj:Object):void {trace(obj);}
as opposed to
Object.prototype.hello = function():void {trace(this);}
Also I had changed my foreach loops to just check for the type when I was using prototypes:
PHP Code:
for each(var thing in bob) {
if(thing is Function) {
//Stuff
}
}
It made it annoying a little bit because it's extra code and you couldn't properly typecast thing:Object otherwise it threw an error when it hit the function.
-
It is surprising to me that thing:Object caused an error. Functions are Objects, as is everything else. What was the particular error thrown?
-
Oh, in that case I believe it was something like looping through an XMLList and trying to cast everything to XML
-
You also have the ability to remove properties from being looped over by using:
setPropertyIsEnumerable(name:String, isEnum:Boolean = true):void
Sets the availability of a dynamic property for loop operations.
-
 Originally Posted by JHarlequin
You also have the ability to remove properties from being looped over by using:
setPropertyIsEnumerable(name:String, isEnum:Boolean = true):void
Sets the availability of a dynamic property for loop operations.
It says this in the help files:
"Sets the availability of a dynamic property for loop operations. The property must exist on the target object because this method does not check the target object's prototype chain. "
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|