Bug

38 views
Skip to first unread message

Olafur Arason

unread,
Jul 29, 2014, 11:32:35 AM7/29/14
to enyo-dev...@googlegroups.com
Hi I tried going through Jira but I don't think I have privileges to submit an issue.

The problem is that when Enyo calls destroyObject it sets this[inName] = null,
and then they don't do delete this[inName]. So what happens in my case where
I'm deleting and creating Components on the fly. The enyo.$ gets filled with
nulled out values which I don't see any need for. There are other cases where 
= null is used, the same way.


I'm wondering if you do an destroyClientControls then you should also clear
_componentNameMap, since the numbers aren't valid any more.

There seem to be a lot of differing options about what to do but we are
dealing with an object that is always changing at least if you add components
then it shouldn't be a problem.


Regards,
Olaf

Cole Davis

unread,
Jul 29, 2014, 1:25:42 PM7/29/14
to enyo-dev...@googlegroups.com
Hi Olaf,

Under what circumstances are you using `destroyObject`? Searching all the way from 2.2.0 to master I can't figure out why using that method would have any impact on the `$` hash of enyo.Component? This method is very old, but works. It should also be noted it is not used (that I can find) in any library maintained by the core team.

/**
* Calls the [destroy()]{@link enyo.Object#destroy} method for the named {@link enyo.Object} 
* property.
*
* @param {String} name The name of the property to destroy, if possible.
* @returns {this} The callee for chaining.
* @public
*/
destroyObject: function (name) {
if (this[name] && this[name].destroy) {
this[name].destroy();
}
this[name] = null;
return this;
},

Something else of interest is that when destroying components (either directly or indirectly via `destroyClientControls`) they wind up setting their `owner` property to null which then forces the `ownerChanged` method to fire and call `removeComponent` on the previous `owner`. Here is the source for that method:

(master)

/**
* Removes the passed-in [component]{@link enyo.Component} from those known
* to be owned by this component. The component will be removed from the
* [$ hash]{@link enyo.Component#$}, and from the [owner]{@link enyo.Component#owner}
* directly if [publish]{@link enyo.Component#publish} is set to `true`.
* @param {enyo.Component} comp The component to remove.
* @returns {this} The callee for chaining.
* @public
*/
removeComponent: function (comp) {
var nom = comp.get('name');
// remove it from the hash if it existed
delete this.$[nom];
// if it was published remove it from the component proper
if (comp.publish) delete this[nom];
return this;
},

(2.4.0)

//* Removes _inComponent_ from the list of components owned by the current
//* component (i.e., _this.$_).
removeComponent: function(inComponent) {
delete this.$[inComponent.getName()];
},

You'll notice it calls `delete` on the `$` hash. So it appears I would need to know more information about your circumstances and use-case to determine why using `destroyObject` has any impact on `$` of a enyo.Component and also why destroying a component would lead to a null value on the `$` hash.

All of that being said, just to weigh in on the null vs delete nature of the question…they each have very specific use-cases. For an operation that may happen many times the fastest possible assignment (afaik in all JavaScript engines) is null while on the other hand the delete operation is one of the slowest and there are many caveats to relying on it. It has its purpose for removing the enumerable property from an object (when that is allowed by the property definition on newer platforms) - and when that is absolutely necessary it should be used. In many if not most cases where delete is used I would argue you can achieve the same outcome more efficiently by using null. Also note that, while it is both easy and convenient (and even in our code blindly used) to throw away an object and assign a new, clean one, that incurs significant overhead depending on the required performance and system it is being executed on. Just like in the case of the delete operation, though, it certainly does have its proper use-cases. Many times the decision is based on the the performance difference between allocating a new object + letting the GC cleanup the old one versus the time it takes to clean the enumerable properties of the given object and reuse it. In some cases, neither is a valid option (such as in JavaScript games) and more creative solutions must be incorporated to maintain higher FPS.

Let us know more about the use-case for hitting those null values on `$`. I'm interested to know how that is happening.

Cheers,

Cole




--
You received this message because you are subscribed to the Google Groups "Enyo Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to enyo-developme...@googlegroups.com.
To post to this group, send email to enyo-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/enyo-development/347a3077-f874-441f-8805-e69075605fde%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages