Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

Comments for delegate(), delegate(), delegate()


Object.create(prototype) will be in the next edition of ECMAScript. It begets.
Bertrand:

We knew of the .NET terminology, but we've been using "delegate()" in this way in Dojo for a long while. The method/object tuple thing is generally called "bind()" in most JS toolkits (we call it hitch()) and the next version of the language will call it 'create()'. Obviously we don't want to confuse anyone, but frankly this hasn't come up before (to the best of my knowledge). Perhaps Dojo folks just haven't been aware of delegate()'s existance? Either way, if it becomes a real problem, we'll give it a new alias.

Bob:

The earliest I knew of it was Aaron Boodman sketching it out on a napkin for me at a bar in the Mission 4 years ago. I think Doug noted the pattern somewhat after that, but the exact timing is fuzzy. I do know that both discovered/noted it independently around the same time.

Regards

by alex at
By the way, one of my new favorite delegation patterns that I like to use to change properties that are accessed during construction, e.g. templatePath in Dijit widgets:

var widget = dojo.delegate(dijit.form.Button.prototype); widget.templatePath = dojo.moduleUrl("some.other", "template.html"); dijit.form.Button.call(widget, {});

In the foo, bar, baz, thud example with aliasing super init methods: any thoughts on schemes on generic aliasing schemes?

Say thud wanted to define init -- it cannot alias baz's init to superInit, since baz already has that name taken.

What I did before was to name it the name of the parent object, so thud aliases init to bazInit, baz aliases init to barInit, etc...

I did not like it because of the dependency on object name, something mutable. It worked out because usually the names did not change. Just curious if there is a better way.

Anyway, interesting stuff. I wonder if aliasing to null should mean delegate deletes the property. So duck type checking like:

if ("testify" in bar)

would return false if bar did a -> testify: null. In that case, maybe make the alias convention should be testify: undefined?

It overlaps with dojox.lang.mix somewhat (added back in September 2008) that sketches out a generic rename/remove functionality. It allows to subset (remove in-place, or copy selectively while mixing) and rename attributes to your liking. There is a simple in-place version for slicing and dicing objects, and more general copying mixing version that supports a concept of filters and decorators for custom mixing algorithms. A bunch of decorators are predefined in the same file. Check it out.

In general I support more generic facilities for OO in Dojo, and I like your lightweight approach.

Speaking about being lightweight: Neil Roberts made an observation long time ago that the for..in loop is inefficient in general (e.g., going over prototypes) and replacing with equivalent assignments can speed things up especially while number of mixed properties is small. It would be nice to have an optional way to bypass the loop in time-critical cases.

Huh, actually dojox.lang.mix was added in August 2008, sorry.
Out of curiosity, do you have any direct references to when boodman/crockford discovered that trick? MochiKit.Base.clone does the same thing, I had never heard of theirs before just now! :)

MochiKit's implementation even does it in a different way entirely, by (ab)using arguments.callee to get the clone function itself and mangle its prototype property. This is not re-entrant or thread-safe but JS doesn't have interrupts or threads so I never bothered to create a "safer" version :)

You might want to check out the .NET concept of delegate before you commit to that name. This could get pretty confusing to many people no matter how useful the concept is.