Hybrid classes based on DOM objects

E

enaeher

Hello,

I've been using the technique described at
http://onjs.com/blog/index.php?title=faux_javascript_constructors_pt_3_return
to create "constructors" for objects which are DOM elements and also
have additional methods, state, etc., e.g.:

function foo (state) {
var that = new document.createElement('div');
that.state = state ? true : false;
that.toggleState = function () { that.state = !(that.state); }
return (that);
}

document.getElementById('someID').appendChild(new foo (false));

This is useful in cases where I'd otherwise be trying to maintain, in
parallel, a tree of DOM elements and a corresponding tree of objects.
It eliminates a good deal of the bookkeeping involved. But it kind of
breaks some things, in that it's not possible to define foo.prototype
(well, you can, but the properties of the prototype aren't applied to
the object returned by new foo()). Inheritance, in particular, gets to
be a pain. Is there a better way to do what I'm trying to do? Is the
whole idea wrong-headed?

Thanks,

--Eli
 
E

Elegie

(e-mail address removed) wrote:

Hi,
function foo (state) {
var that = new document.createElement('div');
that.state = state ? true : false;

that.state=state; // :)

that.toggleState = function () { that.state = !(that.state); }
return (that);
}

document.getElementById('someID').appendChild(new foo (false));

You're using a factory as a constructor, which does work but remains
pretty inelegant. Why not directly use a factory, e.g. makeFoo() ?

But it kind of
breaks some things, in that it's not possible to define foo.prototype
(well, you can, but the properties of the prototype aren't applied to
the object returned by new foo()).

JFYI, in Gecko-based browers, DOM objects are also prototyped and their
prototype can be manipulated; however, since this is not implemented in
other browsers, that technique is not usable for the web.

Now, I a bit perplexed at what pattern you're running after; couldn't
your problem simply be circumvented by using a privileged static object
as "explicit prototype", for instance

var makeExtendedDiv = (function(){
var proto={
'bar' : 42
}

return function(state) {
var div=document.createElement("div");
div.state=state;
div.getPrototype=function(){return proto;};
return div;
}
})();
 
E

enaeher

Elegie said:
You're using a factory as a constructor, which does work but remains
pretty inelegant. Why not directly use a factory, e.g. makeFoo() ?

Yes, that would be clearer -- thanks.
Now, I a bit perplexed at what pattern you're running after; couldn't
your problem simply be circumvented by using a privileged static object
as "explicit prototype", for instance

But anything in that var 'proto' would still be evaluated per-object,
not per-class, right? Or am I mis-reading your code? So far this hasn't
caused me any real problems, aside from the inelegance of not having
prototype properties clearly separated from instance properties, but
I'm wondering if this will cause difficulties down the road.

Basically what I'd like to do is subclass DOMElement (or whatever the
DOM element class is called), but this doesn't seem possible directly.

Thanks,

--Eli
 
E

Elegie

(e-mail address removed) wrote:

Hi,
But anything in that var 'proto' would still be evaluated per-object,
not per-class, right? Or am I mis-reading your code?

IMBW, but I think you might actually be mis-reading it; the variable
'proto' has been made private static, shared by all instances, by using
a closure.

There are two functions in the example:
[1] the outer function is defined and executed at once; the
makeExtendedDiv variable therefore receives the return value of this
execution, and not the outer function itself (which, since being
anonymously defined, is not accessible after having been executed).

[2] the inner function is returned by the outer function and assigned to
the makeExtendedDiv variable (in javascript, functions are first-class
objects). However, being defined in the body of the outer function, it
still has access to the variables of this outer function, even if the
outer function has already returned (javascript has static scoping).

<URL:http://en.wikipedia.org/wiki/Lexical_scoping>
<URL:http://www.jibbering.com/faq/faq_notes/closures.html>
<URL:http://www.litotes.demon.co.uk/js_info/private_static.html>

Trying to access and modify any property of the 'proto' object with two
instances should provide you with a good illustration.

Basically what I'd like to do is subclass DOMElement (or whatever the
DOM element class is called), but this doesn't seem possible directly.

Well, DOM elements are provided by the host, which may or not have them
work with prototypes; hosts are not required to, but they can do it. In
Mozilla for instance, they have been made prototyped and therefore you
could "subclass" them directly, working with 'HTMLDivElement.prototype'
in your example (even though talking about "class" for javascript
matters is quite inappropriate). However other vendors' products, such
as Internet Explorer or Opera, do not expose such mechanisms, which
eventually means you'll have to work with custom prototypes.


HTH.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,828
Latest member
LauraCastr

Latest Threads

Top