Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to ensure memory leak protection?

5 views
Skip to first unread message

Josh Russo

unread,
Jul 20, 2010, 2:22:55 PM7/20/10
to
I'm a little confused about how best to handle user objects that
manage multiple DOM objects.

I was reading https://developer.mozilla.org/en/a_re-introduction_to_javascript
and it seems like my preferred pattern seems like it's exactly what
I'm not suppose to do.

function Widget(){
this.myfield = $('#id_myfield');
var clickHandler = function(event){ //do something };
this.myfield.bind('click', clickHandler);
}

myWdgt = new Widget();

It seems like this is the proper way to handle the issue is this:

function Widget(){
var clickHandler = function(event){ //do something };
(function(){
var myfield = $('#id_myfield');
myfield.bind('click', clickHandler);
})();
}

The only problem with this is that I don't get to cache the query of
MyField. Do I really need to re-query MyField in every method that
needs to use it? It just seems like so much more processing. Though if
that's the only way to avoid the memory leaks then so be it.

The other possibility I see is to capture the window.unload event to
manually destroy my objects. If I do this, is it enough to just
destroy my Widget instances or do I need to destroy the DOM references
individually within each Widget instance?

Thanks so much for your help.

Josh

David Mark

unread,
Jul 20, 2010, 2:58:03 PM7/20/10
to
On Jul 20, 2:22 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
> I'm a little confused about how best to handle user objects that
> manage multiple DOM objects.

Object objects that wrap multiple host objects? Not sure why multiple
matters though.

>
> I was readinghttps://developer.mozilla.org/en/a_re-introduction_to_javascript


> and it seems like my preferred pattern seems like it's exactly what
> I'm not suppose to do.
>
> function Widget(){
>       this.myfield = $('#id_myfield');

Well, that's a big red flag as it indicates one of those ill-conceived
libraries (e.g. jQuery). Why would you use that $ function in lieu of
gEBI?

>       var clickHandler = function(event){ //do something };
>       this.myfield.bind('click', clickHandler);

What about it? There's really no telling what it does exactly without
reading the source of the library. And isn't that what you want to
avoid in the first place. Why not use a simple wrapper for
addEventListener/attachEvent?

>
> }
>
> myWdgt = new Widget();
>
> It seems like this is the proper way to handle the issue is this:
>
> function Widget(){
>       var clickHandler = function(event){ //do something };
>       (function(){
>             var myfield = $('#id_myfield');
>             myfield.bind('click', clickHandler);
>       })();
>
> }

What makes you think that is more proper (or less prone to leaks) than
the above? I assure you it is not. In fact, it's completely bizarre.

>
> The only problem with this is that I don't get to cache the query of
> MyField.

You weren't caching anything in the first place.

> Do I really need to re-query MyField in every method that
> needs to use it?

No, but that question bears little resemblance to the above cases.
There are no method calls in either of them.

> It just seems like so much more processing. Though if
> that's the only way to avoid the memory leaks then so be it.

You are clearly confused about a number of things. Here is some basic
information on the IE memory leak issue:-

http://www.jibbering.com/faq/notes/closures/#clMem

...that is not published by a member of a cargo cult.

>
> The other possibility I see is to capture the window.unload event to
> manually destroy my objects.

Try as you might, you'll never destroy an object in JS. You can
remove all references to an object and eventually the built-in GC will
release the associated resources. That being said, there is no need
to do anything like that in the unload event. That practice became
popular because library developers were trying to solve a problem (of
their own creation) that they didn't understand. Now you are
following in their footsteps.

> If I do this, is it enough to just
> destroy my Widget instances or do I need to destroy the DOM references
> individually within each Widget instance?

You don't need to do anything like that. And the DOM references you
refer to are not "within" the widgets. They are preserved in
closures, which may or may not create circular references. If they do
create such chains then the only way to prevent the leaks in IE is to
remove one or more of the links (e.g. detach the listener from the
element).

Your best bet is to understand the root cause of the problem and stop
using dubious libraries that cloud the issues. Then you can avoid the
problem altogether and never worry about leaks or unload listeners
again.

Josh Russo

unread,
Jul 20, 2010, 3:29:19 PM7/20/10
to
On Jul 20, 5:58 pm, David Mark <dmark.cins...@gmail.com> wrote:
> On Jul 20, 2:22 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
>
> > I'm a little confused about how best to handle user objects that
> > manage multiple DOM objects.
>
> Object objects that wrap multiple host objects?  Not sure why multiple
> matters though.

It doesn't matter. One is enough.

> > I was readinghttps://developer.mozilla.org/en/a_re-introduction_to_javascript
> > and it seems like my preferred pattern seems like it's exactly what
> > I'm not suppose to do.
>
> > function Widget(){
> >       this.myfield = $('#id_myfield');
>
> Well, that's a big red flag as it indicates one of those ill-conceived
> libraries (e.g. jQuery).  Why would you use that $ function in lieu of
> gEBI?

Ok, there's no need to critique my choice libraries. Thanks. The same
would apply if I had said:

this.myfield = document.getElementById('id_myfield');


> >       var clickHandler = function(event){ //do something };
> >       this.myfield.bind('click', clickHandler);
>
> What about it?  There's really no telling what it does exactly without
> reading the source of the library.  And isn't that what you want to
> avoid in the first place.  Why not use a simple wrapper for
> addEventListener/attachEvent?

Because of closures the clickHandler scope keeps the this.myfile in
context. Of course I just realized that the 'this' keyword would be
overridden in the actual call of the click event. When the event is
called 'this' will be the myfield instance. The following is a better
example:

function Widget(){


var myfield = $('#id_myfield');

var clickHandler = function(event){ //do something };

myfield.bind('click', clickHandler);
}

Here the myfield DOM object has a circular reference to itself via the
myfield variable.

> > }
>
> > myWdgt = new Widget();
>
> > It seems like this is the proper way to handle the issue is this:
>
> > function Widget(){
> >       var clickHandler = function(event){ //do something };
> >       (function(){
> >             var myfield = $('#id_myfield');
> >             myfield.bind('click', clickHandler);
> >       })();
>
> > }
>
> What makes you think that is more proper (or less prone to leaks) than
> the above?  I assure you it is not.  In fact, it's completely bizarre.

It's more correct because the myfield var goes out of scope after use
because the clickHandler can't see it.


> > The only problem with this is that I don't get to cache the query of
> > MyField.
>
> You weren't caching anything in the first place.

I was caching the reference to the DOM object id_myfield in
this.myfield, of course var myfield would accomplish the same goal
without making it a public property. My goal is to not have to use
getElementById or any other querying mechanism every time I want to
use a field.


> > Do I really need to re-query MyField in every method that
> > needs to use it?
>
> No, but that question bears little resemblance to the above cases.
> There are no method calls in either of them.

Ok, you are correct. I didn't add them explicitly, I figured people
could envision what I was referring to. Here's an example:


function Widget(){
this.myfield = $('#id_myfield');

var clickHandler = function(event){ //do something };
this.myfield.bind('click', clickHandler);

this.setField = function(txt){
this.myfield.val(txt); // Yes it's jQuery syntax
}
}


> > It just seems like so much more processing. Though if
> > that's the only way to avoid the memory leaks then so be it.
>
> You are clearly confused about a number of things.  Here is some basic
> information on the IE memory leak issue:-
>
> http://www.jibbering.com/faq/notes/closures/#clMem
>
> ...that is not published by a member of a cargo cult.

The document you directed me to explains exactly the situation I'm
referring to. This is directly from that page:

Closures are extremely good at forming circular references. If a
function object that forms a closure is assigned as, for example, and
event handler on a DOM Node, and a reference to that Node is assigned
to one of the Activation/Variable objects in its scope chain then a
circular reference exists. DOM_Node.onevent -> function_object.
[[scope]] -> scope_chain -> Activation_object.nodeRef -> DOM_Node. It
is very easy to do, and a bit of browsing around a site that forms
such a reference in a piece of code common to each page can consume
most of the systems memory (possibly all).


> > The other possibility I see is to capture the window.unload event to
> > manually destroy my objects.
>
> Try as you might, you'll never destroy an object in JS.  You can
> remove all references to an object and eventually the built-in GC will
> release the associated resources.  That being said, there is no need
> to do anything like that in the unload event.  That practice became
> popular because library developers were trying to solve a problem (of
> their own creation) that they didn't understand.  Now you are
> following in their footsteps.

Ok, so what you just did was answer the next part of my question. I
may need to manually dereference the individual references, using the
delete command.

> > If I do this, is it enough to just
> > destroy my Widget instances or do I need to destroy the DOM references
> > individually within each Widget instance?
>
> You don't need to do anything like that.  And the DOM references you
> refer to are not "within" the widgets.  They are preserved in
> closures, which may or may not create circular references.  If they do
> create such chains then the only way to prevent the leaks in IE is to
> remove one or more of the links (e.g. detach the listener from the
> element).

They are in a circular reference as described by the page you
referenced.

David Mark

unread,
Jul 20, 2010, 4:37:02 PM7/20/10
to
On Jul 20, 3:29 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
> On Jul 20, 5:58 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> > On Jul 20, 2:22 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
>
> > > I'm a little confused about how best to handle user objects that
> > > manage multiple DOM objects.
>
> > Object objects that wrap multiple host objects?  Not sure why multiple
> > matters though.
>
> It doesn't matter. One is enough.
>
> > > I was readinghttps://developer.mozilla.org/en/a_re-introduction_to_javascript
> > > and it seems like my preferred pattern seems like it's exactly what
> > > I'm not suppose to do.
>
> > > function Widget(){
> > >       this.myfield = $('#id_myfield');
>
> > Well, that's a big red flag as it indicates one of those ill-conceived
> > libraries (e.g. jQuery).  Why would you use that $ function in lieu of
> > gEBI?
>
> Ok, there's no need to critique my choice libraries.

You would do well to listen. It's not just the odd $ function that I
dislike about it. The fact is that the code throughout is of very
poor quality.

> Thanks. The same
> would apply if I had said:
>
> this.myfield = document.getElementById('id_myfield');

But that's totally different as gEBI returns a host object reference.
The jQuery thing returns an Object object. See how using a library at
a point where you don't understand the basics can be confusing? Along
the same lines, you are likely not ready to judge the quality (or lack
thereof) of the libraries either.

>
> > >       var clickHandler = function(event){ //do something };
> > >       this.myfield.bind('click', clickHandler);
>
> > What about it?  There's really no telling what it does exactly without
> > reading the source of the library.  And isn't that what you want to
> > avoid in the first place.  Why not use a simple wrapper for
> > addEventListener/attachEvent?
>
> Because of closures the clickHandler scope keeps the this.myfile in
> context.

You are confused. The - this - keyword is not part of the scope
chain. There is no reference to a host object in the scope of your
listener function and furthermore, the library is unlikely to attach
that function as the listener (more likely it wraps it, but again
there's no telling without delving into jQuery). Until you understand
these concepts, libraries will just make such potential issues harder
to spot.

> Of course I just realized that the 'this' keyword would be
> overridden in the actual call of the click event.

Very likely it will reference the element, but that doesn't matter.

> When the event is
> called 'this' will be the myfield instance.

There are no instances in JS and "myfield" is the name of a property
of your constructed object, which references another Object object
(not a host object). That's if you are using jQuery. If it is
Prototype or MooTools, it will reference a host object, but it still
won't matter as the - this - keyword is not part of the scope chain.

> The following is a better
> example:
>
> function Widget(){
>       var myfield = $('#id_myfield');
>       var clickHandler = function(event){ //do something };
>       myfield.bind('click', clickHandler);
>
> }
>
> Here the myfield DOM object has a circular reference to itself via the
> myfield variable.

If the myfield variable references an element (host object) rather
than some sort of wrapper (Object object) then this could possibly be
a leaky pattern. But I find it extremely unlikely that the bind
method attaches your clickHandler function as the listener (more
likely it wraps it in another function). Again, it's hard to say
without looking into the library code (which is likely what you are
trying to avoid by using a library). By using such a library, you
have created problems for yourself, as well as for anyone who would
try to debug the code (e.g. me).

>
>
>
>
>
> > > }
>
> > > myWdgt = new Widget();
>
> > > It seems like this is the proper way to handle the issue is this:
>
> > > function Widget(){
> > >       var clickHandler = function(event){ //do something };
> > >       (function(){
> > >             var myfield = $('#id_myfield');
> > >             myfield.bind('click', clickHandler);
> > >       })();
>
> > > }
>
> > What makes you think that is more proper (or less prone to leaks) than
> > the above?  I assure you it is not.  In fact, it's completely bizarre.
>
> It's more correct because the myfield var goes out of scope after use
> because the clickHandler can't see it.

That indicates some understanding of the problem; but again, it is
unclear whether there was a problem in the first place.

And why not do this:-

function Widget() {
var el = document.getElementById('id_myfield');

el.onclick = function() {
// Do something
};
el = null;
}

It should be clear that without the last line, there would be a
circular reference involving a host object (and therefore it would
leak in some versions of IE). Also, the - this - keyword will
reference the element, so you don't need to preserve it.

If your listener will need a reference to the constructed object,
add:-

var that = this;

If you don't need a reference to your constructed object, you could do
this:-

function clickListener() {
// Do something
}

function Widget() {
var el = document.getElementById('id_myfield');

el.onclick = clickListener;
}

Hard to say from your examples, but assuming you do need such a
reference:-

function createClickListener(that) {
return function() {
// Do something
};
}

function Widget() {
var el = document.getElementById('id_myfield');

el.onclick = createClickListener(this);
}

>
> > > The only problem with this is that I don't get to cache the query of
> > > MyField.
>
> > You weren't caching anything in the first place.
>
> I was caching the reference to the DOM object id_myfield in
> this.myfield, of course var myfield would accomplish the same goal
> without making it a public property.

I didn't see how you considered that caching as every call to the
constructor would repeat that operation. But I see what you are
getting at now.

> My goal is to not have to use
> getElementById or any other querying mechanism every time I want to
> use a field.

You haven't posted any examples that use the element (or wrapped
element) reference, so it is hard to follow what you are trying to do.

>
> > > Do I really need to re-query MyField in every method that
> > > needs to use it?
>
> > No, but that question bears little resemblance to the above cases.
> > There are no method calls in either of them.
>
> Ok, you are correct. I didn't add them explicitly, I figured people
> could envision what I was referring to.

There are few mind-readers here.

Here's an example:
> function Widget(){
>       this.myfield = $('#id_myfield');
>       var clickHandler = function(event){ //do something };
>       this.myfield.bind('click', clickHandler);
>
>       this.setField = function(txt){
>          this.myfield.val(txt); // Yes it's jQuery syntax
>       }
>
> }

And there are very few who care to dig through jQuery to determine
whether your assumptions about its methods are correct. But
regardless, the above has no circular reference (with or without
jQuery). The - this - keyword is not part of the scope chain and
jQuery's "$" method does not return host objects anyway. The only
thing that could create leaks here is jQuery and therefore the only
way to know for sure whether leaks will occur is to read jQuery's
code, which negates the benefit of using the library.

Consider this more readable alternative, which does not require any
odd patteners or an additional 70K of junk code:-

function createClickListener(that) {
return function() {
// Do something with this and that
};
}

function Widget(){
      el = document.getElementById('id_myfield');
      el.onclick = createClickListener(this);

      this.setField = function(txt) {
         el.value = txt;
      };
}

In your listener - this - will refer to the element and - that - will
refer to the widget object.

That's much faster, more readable and obviously much less code to pore
over and maintain.

> > > It just seems like so much more processing. Though if
> > > that's the only way to avoid the memory leaks then so be it.
>
> > You are clearly confused about a number of things.  Here is some basic
> > information on the IE memory leak issue:-
>
> >http://www.jibbering.com/faq/notes/closures/#clMem
>
> > ...that is not published by a member of a cargo cult.
>
> The document you directed me to explains exactly the situation I'm
> referring to.

But apparently you did not understand it.

> This is directly from that page:
>
> Closures are extremely good at forming circular references. If a
> function object that forms a closure is assigned as, for example, and
> event handler on a DOM Node, and a reference to that Node is assigned
> to one of the Activation/Variable objects in its scope chain then a
> circular reference exists. DOM_Node.onevent -> function_object.
> [[scope]] -> scope_chain -> Activation_object.nodeRef -> DOM_Node. It
> is very easy to do, and a bit of browsing around a site that forms
> such a reference in a piece of code common to each page can consume
> most of the systems memory (possibly all).

Yes, I've read it. But pasting snippets here will not help you
understand why - this - is not part of the scope chain.

>
> > > The other possibility I see is to capture the window.unload event to
> > > manually destroy my objects.
>
> > Try as you might, you'll never destroy an object in JS.  You can
> > remove all references to an object and eventually the built-in GC will
> > release the associated resources.  That being said, there is no need
> > to do anything like that in the unload event.  That practice became
> > popular because library developers were trying to solve a problem (of
> > their own creation) that they didn't understand.  Now you are
> > following in their footsteps.
>
> Ok, so what you just did was answer the next part of my question. I
> may need to manually dereference the individual references, using the
> delete command.

Not in the case of your examples as - this - is not part of the scope
chain.

>
> > > If I do this, is it enough to just
> > > destroy my Widget instances or do I need to destroy the DOM references
> > > individually within each Widget instance?
>
> > You don't need to do anything like that.  And the DOM references you
> > refer to are not "within" the widgets.  They are preserved in
> > closures, which may or may not create circular references.  If they do
> > create such chains then the only way to prevent the leaks in IE is to
> > remove one or more of the links (e.g. detach the listener from the
> > element).
>
> They are in a circular reference as described by the page you
> referenced.

Which you have failed to understand completely.

Josh Russo

unread,
Jul 20, 2010, 7:51:37 PM7/20/10
to
Ok, lets start over.

First off I know exactly what jQuery is doing behind the scenes. The
object that it creates extends the array class. Each element of said
array is a DOM object. All additional jQuery helper methods are added
to the extended array class. Are you saying that because the DOM
elements are elements of a fancy array that it's no longer a circular
reference? That doesn't sound right. Maybe if these array elements
were not publicly accessible, but they are, so it sees that there
would still be a circular reference using a jQuery object as opposed
to a direct DOM element.

I guess the crux of my difficulty is that I want to avoid multiple
calls to methods like gEBI or $(). I think you hit my solution with
this bit:

function clickListener() {
// Do something
}

function Widget() {
var el = document.getElementById('id_myfield');
el.onclick = clickListener;
}

I just got too wrapped up in having everything encapsulated in the
class/function.

Thanks for talking me through that.

David Mark

unread,
Jul 20, 2010, 8:57:53 PM7/20/10
to
On Jul 20, 7:51 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
> Ok, lets start over.
>
> First off I know exactly what jQuery is doing behind the scenes.

That would tend to contradict your previous questions regarding your
examples. And why waste time being defensive?

> The
> object that it creates extends the array class.

There is no such thing as an "array class" and jQuery doesn't extend
anything native. Clearly you are very confused. I know that sounds
harsh, but it is what you need to hear at this point. You might feel
compelled to blame me for your confusion (and possible frustration at
this point), but it is surely schlock like Prototype, Dojo, MooTools,
ExtJS, etc. that has led you astray. jQuery's code is less schlocky
in this regard, but the community is such a cargo cult that I'm sure
they repeat such misconceptions about "classes", "singletons", scope,
etc. Granted, you seem to have scope about half right (which is above
the industry average).

The objects that jQuery's "$" function return are somewhat array-like
but have nothing to do with arrays. They are simply Object objects
(as opposed to Array objects).

> Each element of said
> array is a DOM object.

I'm imagine it does maintain an array internally. And I believe it
mirrors the DOM references as properties of the object. That is
certainly a bad idea. In the case of one of your examples, you
*might* have had this chain:-

[jQuery object]->[DOM node]->[listener function]->[Activation Object]-
>[jQuery object]

But certainly that would not be the case where you "cached" the
reference to the element as a property of your constructed object as
the fourth link in that chain would not exist. Furthermore, in your
other examples, assuming jQuery wraps listeners (a good bet as it
allows you to set the - this - object), the same link would be
broken. So it seems likely that you are chasing phantoms.

> All additional jQuery helper methods are added
> to the extended array class.

See above about that. Realize that JS uses prototypal (not classical)
inheritance. The "helper methods" you refer to are on the jQuery
object's prototype (jquery.fn IIRC).

> Are you saying that because the DOM
> elements are elements of a fancy array that it's no longer a circular
> reference?

Certainly not as there is no such thing as a "fancy array".

> That doesn't sound right. Maybe if these array elements
> were not publicly accessible, but they are, so it sees that there
> would still be a circular reference using a jQuery object as opposed
> to a direct DOM element.

Except for the reasons I already pointed out (e.g. the - this -
keyword is not part of the scope chain).

>
> I guess the crux of my difficulty is that I want to avoid multiple
> calls to methods like gEBI or $(). I think you hit my solution with
> this bit:
>
> function clickListener() {
>   // Do something
>
> }
>
> function Widget() {
>   var el = document.getElementById('id_myfield');
>   el.onclick = clickListener;
>
> }
>
> I just got too wrapped up in having everything encapsulated in the
> class/function.
>
> Thanks for talking me through that.

NP at all. Best of luck!

Josh Russo

unread,
Jul 21, 2010, 5:45:16 AM7/21/10
to
On Jul 20, 11:57 pm, David Mark <dmark.cins...@gmail.com> wrote:
> On Jul 20, 7:51 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
>
> > Ok, lets start over.
>
> > First off I know exactly what jQuery is doing behind the scenes.
>
> That would tend to contradict your previous questions regarding your
> examples.  And why waste time being defensive?

My question wasn't about how jQuery works. I was already convinced
that the object created by jQuery was creating the same scenario you
have if you had a direct DOM reference instead. In other words you can
replace any $() calls with gEBI and have the same scenario. My
question, if you reference my original post, was about user object
creation patterns.

People tend to get defensive when you criticize instead of just asking
question about their methods. You may have asked questions, but in a
very critical manner.


> > The
> > object that it creates extends the array class.
>
> There is no such thing as an "array class" and jQuery doesn't extend
> anything native.  Clearly you are very confused.  I know that sounds
> harsh, but it is what you need to hear at this point.  You might feel
> compelled to blame me for your confusion (and possible frustration at
> this point), but it is surely schlock like Prototype, Dojo, MooTools,
> ExtJS, etc. that has led you astray.  jQuery's code is less schlocky
> in this regard, but the community is such a cargo cult that I'm sure
> they repeat such misconceptions about "classes", "singletons", scope,
> etc.  Granted, you seem to have scope about half right (which is above
> the industry average).
>
> The objects that jQuery's "$" function return are somewhat array-like
> but have nothing to do with arrays.  They are simply Object objects
> (as opposed to Array objects).

You are correct. I took a look again and they are creating objects
with array like properties. What I thought they were doing was adding
custom functions/methods to an array instance.

I have only a cursory understanding of prototyping. I thought it was
just in memory classes. I will make sure I understand it and use it's
terminology more.

By the way, what in the world do you mean by a cargo cult?


> > Each element of said
> > array is a DOM object.
>
> I'm imagine it does maintain an array internally.  And I believe it
> mirrors the DOM references as properties of the object.  That is
> certainly a bad idea.  In the case of one of your examples, you
> *might* have had this chain:-
>
> [jQuery object]->[DOM node]->[listener function]->[Activation Object]-
>
> >[jQuery object]
>
> But certainly that would not be the case where you "cached" the
> reference to the element as a property of your constructed object as
> the fourth link in that chain would not exist.  Furthermore, in your
> other examples, assuming jQuery wraps listeners (a good bet as it
> allows you to set the - this - object), the same link would be
> broken.  So it seems likely that you are chasing phantoms.

Yes I realize now that I will be safe if I setup the DOM reference as
a public property of the my Widget object using the 'this' keyword.
There is a problem though if I want to make the DOM reference private
by using 'var' instead.

Erwin Moller

unread,
Jul 21, 2010, 6:20:01 AM7/21/10
to
Josh Russo schreef:

>
> By the way, what in the world do you mean by a cargo cult?
>

http://en.wikipedia.org/wiki/Cargo_cult_programming

which is based on Richard Feynman original:

http://en.wikipedia.org/wiki/Cargo_cult_science

The other issues I rather leave to David to answer. ;-)

Regards,
Erwin Moller

--
"There are two ways of constructing a software design: One way is to
make it so simple that there are obviously no deficiencies, and the
other way is to make it so complicated that there are no obvious
deficiencies. The first method is far more difficult."
-- C.A.R. Hoare

David Mark

unread,
Jul 22, 2010, 2:17:14 AM7/22/10
to
On Jul 21, 5:45 am, Josh Russo <josh.r.ru...@gmail.com> wrote:
> On Jul 20, 11:57 pm, David Mark <dmark.cins...@gmail.com> wrote:
>
> > On Jul 20, 7:51 pm, Josh Russo <josh.r.ru...@gmail.com> wrote:
>
> > > Ok, lets start over.
>
> > > First off I know exactly what jQuery is doing behind the scenes.
>
> > That would tend to contradict your previous questions regarding your
> > examples.  And why waste time being defensive?
>
> My question wasn't about how jQuery works.

But you posted a code snippet without even specifying that jQuery was
in use.

> I was already convinced
> that the object created by jQuery was creating the same scenario you
> have if you had a direct DOM reference instead.

But you apparently didn't realize how jQuery attaches listeners.

> In other words you can
> replace any $() calls with gEBI and have the same scenario. My
> question, if you reference my original post, was about user object
> creation patterns.

And there was a huge hole in the example you posted, which inhibited
prospective respondents from deducing what your real problem was (or
if there was a problem at all). If your question was strictly about
JS patterns, you should have posted a "pure" example (i.e. one that
did not call functions in a black hole).

>
> People tend to get defensive when you criticize instead of just asking
> question about their methods.

I didn't criticize you at all.

> You may have asked questions, but in a
> very critical manner.

Critical thinking requires critical questions. Though perhaps you
have another take on that term.

I was only asking such questions to get to the bottom of your problem
and to save both of us some time in the process. You should also
remember this is not a help desk.

>
>
>
>
>
> > > The
> > > object that it creates extends the array class.
>
> > There is no such thing as an "array class" and jQuery doesn't extend
> > anything native.  Clearly you are very confused.  I know that sounds
> > harsh, but it is what you need to hear at this point.  You might feel
> > compelled to blame me for your confusion (and possible frustration at
> > this point), but it is surely schlock like Prototype, Dojo, MooTools,
> > ExtJS, etc. that has led you astray.  jQuery's code is less schlocky
> > in this regard, but the community is such a cargo cult that I'm sure
> > they repeat such misconceptions about "classes", "singletons", scope,
> > etc.  Granted, you seem to have scope about half right (which is above
> > the industry average).
>
> > The objects that jQuery's "$" function return are somewhat array-like
> > but have nothing to do with arrays.  They are simply Object objects
> > (as opposed to Array objects).
>
> You are correct. I took a look again and they are creating objects
> with array like properties. What I thought they were doing was adding
> custom functions/methods to an array instance.

There are no instances in JS. :)

>
> I have only a cursory understanding of prototyping.

Clearly and that is a major obstacle for JS proficiency. Part of my
"criticism" was to alert you to that fact.

> I thought it was
> just in memory classes.

I don't know what that means.

> I will make sure I understand it and use it's
> terminology more.

You are welcome. :)

>
> By the way, what in the world do you mean by a cargo cult?

That's been answered in a follow-up. JFTR, jQuery is one of the
biggest (and loudest).

>
>
>
> > > Each element of said
> > > array is a DOM object.
>
> > I'm imagine it does maintain an array internally.  And I believe it
> > mirrors the DOM references as properties of the object.  That is
> > certainly a bad idea.  In the case of one of your examples, you
> > *might* have had this chain:-
>
> > [jQuery object]->[DOM node]->[listener function]->[Activation Object]-
>
> > >[jQuery object]
>
> > But certainly that would not be the case where you "cached" the
> > reference to the element as a property of your constructed object as
> > the fourth link in that chain would not exist.  Furthermore, in your
> > other examples, assuming jQuery wraps listeners (a good bet as it
> > allows you to set the - this - object), the same link would be
> > broken.  So it seems likely that you are chasing phantoms.
>
> Yes I realize now that I will be safe if I setup the DOM reference as
> a public property of the my Widget object using the 'this' keyword.

Well, if you knew that before, why did you post examples that assumed
such an arrangement would leak?

> There is a problem though if I want to make the DOM reference private
> by using 'var' instead.

There could be. As mentioned, it depends on how your library attaches
listeners.

David Mark

unread,
Jul 22, 2010, 2:19:27 AM7/22/10
to

Thomas 'PointedEars' Lahn

unread,
Jul 22, 2010, 2:47:33 AM7/22/10
to
Josh Russo wrote:

> First off I know exactly what jQuery is doing behind the scenes.

You think you do, but you don't. For not even its author(s) do(es). We've
be over this ad nauseam. You would be well-advised to read before you post.


PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300...@news.demon.co.uk> (2004)

Thomas 'PointedEars' Lahn

unread,
Jul 22, 2010, 2:53:09 AM7/22/10
to
David Mark wrote:

> Josh Russo wrote:


>> David Mark wrote:
>> > The objects that jQuery's "$" function return are somewhat array-like
>> > but have nothing to do with arrays. They are simply Object objects
>> > (as opposed to Array objects).
>>
>> You are correct. I took a look again and they are creating objects
>> with array like properties. What I thought they were doing was adding
>> custom functions/methods to an array instance.

^^^^^


> There are no instances in JS. :)

Wrong. You want to read the ECMAScript Language Specification, any Edition.

The term that has been used here is only incorrect in that it should have
been a capital `A' at the beginning.


PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee

David Mark

unread,
Jul 22, 2010, 3:24:04 AM7/22/10
to
On Jul 22, 2:53 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> David Mark wrote:
> > Josh Russo wrote:
> >> David Mark wrote:
> >> > The objects that jQuery's "$" function return are somewhat array-like
> >> > but have nothing to do with arrays.  They are simply Object objects
> >> > (as opposed to Array objects).
>
> >> You are correct. I took a look again and they are creating objects
> >> with array like properties. What I thought they were doing was adding
> >> custom functions/methods to an array instance.
>
>                                   ^^^^^
>
> > There are no instances in JS.  :)
>
> Wrong.  You want to read the ECMAScript Language Specification, any Edition.

ISTM that the term instances is associated with classes, of which
there are none in JS. Of course the language used in specifications
can often be confusing when dropped into a general discussion. For
example, the DOM specifications refer to DOM properties as some sort
of attributes.

And, as has been discussed repeatedly, the instanceof operator has an
unfortunate name. This may have been a case of the language designers
letting the low-level terminology bubble up into the language itself.
In any event, that name has caused confusion.

>
> The term that has been used here is only incorrect in that it should have
> been a capital `A' at the beginning.
>

I would have called it an Array object. Doesn't that make more
sense? Like all JS objects, it is constructed, not instantiated.

Josh Russo

unread,
Jul 22, 2010, 5:08:39 AM7/22/10
to
Ok, my original post assumed too much. I should have made the
following statements clear:

1) The jQuery object reference offers the same pit falls as a
variable containing a DOM reference because the contained DOM
reference is publicly accessible within the jQuery object

2) Here I was going to say that the bind method works sufficiently
similar to the direct event binding but that doesn't even matter in
this case. What matter is the scope of the event listener function
when it's declared. So #1 is the only thing I really missed in my
original post.

If there are no instances in JS, how do you refer to X and Y below?

var X = [];
var Y = [];

As for learning more about prototyping and how it's different, do you
have a recommendation for a good reference website?

David Mark

unread,
Jul 22, 2010, 6:50:36 AM7/22/10
to
On Jul 22, 5:08 am, Josh Russo <josh.r.ru...@gmail.com> wrote:
> Ok, my original post assumed too much. I should have made the
> following statements clear:
>
>    1) The jQuery object reference offers the same pit falls as a
> variable containing a DOM reference because the contained DOM
> reference is publicly accessible within the jQuery object

Yes, that would have been very helpful for those attempting to
understand the problem or determine whether there actually was a
problem to solve.

>
>    2) Here I was going to say that the bind method works sufficiently
> similar to the direct event binding but that doesn't even matter in
> this case.

Yes, it certainly does.

> What matter is the scope of the event listener function
> when it's declared.

In the case we have been discussing, the listener attached by jQuery
is not declared at all. It's created with a function expression
inside of a jQuery method. What do you figure its scope to be?
That's right, you will have to slog through jQuery's code again to
determine whether it is minding its business with regard to avoiding
circular references. What your code does is actually immaterial.
Confusing and time-consuming isn't it?

> So #1 is the only thing I really missed in my
> original post.

Do you recall that article by Richard Cornford that I cited and you
quoted a few messages back? You should read it again.

>
> If there are no instances in JS, how do you refer to X and Y below?
>
> var X = [];
> var Y = [];

Bad form? :) But seriously, the X and Y variables refer to Array
objects.

>
> As for learning more about prototyping and how it's different, do you
> have a recommendation for a good reference website?

I know at least one good article (see above).

And, of course, Crockford has written extensively on the subject as
well.

http://www.crockford.com

Glad you could take something out of this discussion. You'll very
likely become a better programmer for it. Kudos for asking here
rather than in the jQuery forums. There you would have likely gotten
a bunch of "try this" responses with instructions to gaze at the Task
Manager to gauge their effectiveness. It may have been a more
pleasant experience (like visiting a tropical island with endearing
natives), but you would have wasted time and learned nothing (probably
leading to more wasted time in the future).

Josh Russo

unread,
Jul 22, 2010, 9:48:07 AM7/22/10
to
On Jul 22, 9:50 am, David Mark <dmark.cins...@gmail.com> wrote:
> On Jul 22, 5:08 am, Josh Russo <josh.r.ru...@gmail.com> wrote:
> >    2) Here I was going to say that the bind method works sufficiently
> > similar to the direct event binding but that doesn't even matter in
> > this case.
>
> Yes, it certainly does.
>
> > What matter is the scope of the event listener function
> > when it's declared.
>
> In the case we have been discussing, the listener attached by jQuery
> is not declared at all.  It's created with a function expression
> inside of a jQuery method.  What do you figure its scope to be?
> That's right, you will have to slog through jQuery's code again to
> determine whether it is minding its business with regard to avoiding
> circular references.  What your code does is actually immaterial.
> Confusing and time-consuming isn't it?

Ok now you lost me. The lines in question are these:

var clickHandler = function(event){ //do something };
this.myfield.bind('click', clickHandler);

This is not within a jQuery method. jQuery merely stores the reference
that I pass to it. The clickHandler function right there outside of
the jQuery object, or am I missing something?

> > So #1 is the only thing I really missed in my
> > original post.
>
> Do you recall that article by Richard Cornford that I cited and you
> quoted a few messages back?  You should read it again.
>
>
>
> > If there are no instances in JS, how do you refer to X and Y below?
>
> > var X = [];
> > var Y = [];
>
> Bad form?  :)  But seriously, the X and Y variables refer to Array
> objects.

Why is this bad form?

I understand that X and Y refer to Array objects but I'm looking from
the variables perspective, I'm talking about how to refer to them from
my perspective. Would they not be Array object instances?


> > As for learning more about prototyping and how it's different, do you
> > have a recommendation for a good reference website?
>
> I know at least one good article (see above).

Are you referring to the jibbering.com url?


> And, of course, Crockford has written extensively on the subject as
> well.
>
> http://www.crockford.com
>
> Glad you could take something out of this discussion.  You'll very
> likely become a better programmer for it.  Kudos for asking here
> rather than in the jQuery forums.  There you would have likely gotten
> a bunch of "try this" responses with instructions to gaze at the Task
> Manager to gauge their effectiveness.  It may have been a more
> pleasant experience (like visiting a tropical island with endearing
> natives), but you would have wasted time and learned nothing (probably
> leading to more wasted time in the future).

I always want to know how things really work and in that it helps to
speak the language so everyone is on the same page.

Asen Bozhilov

unread,
Jul 22, 2010, 9:50:24 AM7/22/10
to
Josh Russo wrote:

> I'm a little confused about how best to handle user objects that
> manage multiple DOM objects.
>

> I was readinghttps://developer.mozilla.org/en/a_re-introduction_to_javascript


> and it seems like my preferred pattern seems like it's exactly what
> I'm not suppose to do.
>
> function Widget(){
>       this.myfield = $('#id_myfield');
>       var clickHandler = function(event){ //do something };
>       this.myfield.bind('click', clickHandler);
>
> }

Just rewrite it in a proper way.

var Widget = (function () {
function onClick(evt) {
//...
}

return function (widgetId) {
this.myfield = document.getElementById(widgetId);

util.addListener(this.myfield, 'click', onClick);
};
})();

/**
* Do something with `myfield' member
*/
Widget.prototype.method = function () {
//...
};

Josh Russo

unread,
Jul 22, 2010, 10:16:47 AM7/22/10
to

Yes, I have started using the above pattern for creation of user
objects. I still need to understand the mechanics of prototyping more,
but this thread was me just trying to solidify my understanding of why
the previous pattern was bad.

Once I hit the point in this thread that I really understood what
needed to be looked for, a review of my code found none of the
patterns I thought I had created. My simplified example didn't
actually exist in the many different way my object creation patterns
have evolved. Go figure.

John G Harris

unread,
Jul 22, 2010, 10:16:58 AM7/22/10
to
On Thu, 22 Jul 2010 at 00:24:04, in comp.lang.javascript, David Mark
wrote:

<snip>


>ISTM that the term instances is associated with classes, of which
>there are none in JS.

'Instance' is associated with anything that is one of many. You have
said, I seem to remember, that there are no singleton objects in JS, so
every object must be one of many somethings.


<snip>


>I would have called it an Array object.

You are using 'Array' as an adjective here. This is just a short way of
saying that it's an object that was created by the constructor named
Array.

Either way, the object is a member of the class of all possible such
objects.


>Doesn't that make more
>sense? Like all JS objects, it is constructed, not instantiated.

I don't believe there is any substantial difference between construct
and instantiate.

Occasionally you might want to distinguish between construction, which
does not include allocating space for the object, and instantiation
which often does, as in a factory method.


John
--
John Harris

Gregor Kofler

unread,
Jul 22, 2010, 11:02:24 AM7/22/10
to
Am 2010-07-22 15:48, Josh Russo meinte:

> Ok now you lost me. The lines in question are these:
>
> var clickHandler = function(event){ //do something };
> this.myfield.bind('click', clickHandler);
>
> This is not within a jQuery method. jQuery merely stores the reference
> that I pass to it. The clickHandler function right there outside of
> the jQuery object, or am I missing something?

You are passing a reference, but it will not get "merely stored".
Instead it will be wrapped and fiddled with by jQuery (for cross-browser
"normalization" and such stuff).

>>> var X = [];
>>> var Y = [];
>>
>> Bad form? :) But seriously, the X and Y variables refer to Array
>> objects.
>
> Why is this bad form?

It is recommended to use upper case variable names for constructor
functions only.

> I always want to know how things really work and in that it helps to
> speak the language so everyone is on the same page.

With this attitude, you will never become a good script kiddie...

Gregor


--
http://www.gregorkofler.com

Josh Russo

unread,
Jul 22, 2010, 11:15:57 AM7/22/10
to
On Jul 22, 2:02 pm, Gregor Kofler <use...@gregorkofler.com> wrote:
> Am 2010-07-22 15:48, Josh Russo meinte:
>
> > Ok now you lost me. The lines in question are these:
>
> >        var clickHandler = function(event){ //do something };
> >        this.myfield.bind('click', clickHandler);
>
> > This is not within a jQuery method. jQuery merely stores the reference
> > that I pass to it. The clickHandler function right there outside of
> > the jQuery object, or am I missing something?
>
> You are passing a reference, but it will not get "merely stored".
> Instead it will be wrapped and fiddled with by jQuery (for cross-browser
> "normalization" and such stuff).

Ok, but the important part for this discussion is that it still
maintains it's original variable scope, and I believe it does. I will
have to confirm that.

>
> >>> var X = [];
> >>> var Y = [];
>
> >> Bad form?  :)  But seriously, the X and Y variables refer to Array
> >> objects.
>
> > Why is this bad form?
>
> It is recommended to use upper case variable names for constructor
> functions only.

LOL Is that all he was referring to? Ok. I thought it was the square
braces instead of 'new Array()'.

>
> > I always want to know how things really work and in that it helps to
> > speak the language so everyone is on the same page.
>
> With this attitude, you will never become a good script kiddie...

Damn! My life's dream shattered!

Gregor Kofler

unread,
Jul 22, 2010, 12:03:35 PM7/22/10
to
Am 2010-07-22 17:15, Josh Russo meinte:

>>>>> var X = [];
>>>>> var Y = [];
>>
>>>> Bad form? :) But seriously, the X and Y variables refer to Array
>>>> objects.
>>
>>> Why is this bad form?
>>
>> It is recommended to use upper case variable names for constructor
>> functions only.
>
> LOL Is that all he was referring to? Ok. I thought it was the square
> braces instead of 'new Array()'.

The square bracket notation is the preferred way to define array values.

Gregor

--
http://www.gregorkofler.com

Richard Cornford

unread,
Jul 22, 2010, 1:34:21 PM7/22/10
to
On Jul 22, 2:48 pm, Josh Russo wrote:
> On Jul 22, 9:50 am, David Mark wrote:
>> On Jul 22, 5:08 am, Josh Russo wrote:
<snip>

>>> What matter is the scope of the event listener function
>>> when it's declared.
>
>> In the case we have been discussing, the listener attached
>> by jQuery is not declared at all. It's created with a
>> function expression inside of a jQuery method. What do
>> you figure its scope to be? That's right, you will have to
>> slog through jQuery's code again to determine whether it is
>> minding its business with regard to avoiding circular
>> references. What your code does is actually immaterial.
>> Confusing and time-consuming isn't it?
>
> Ok now you lost me. The lines in question are these:
>
> var clickHandler = function(event){ //do something };
> this.myfield.bind('click', clickHandler);
>
> This is not within a jQuery method. jQuery merely stores the
> reference that I pass to it. The clickHandler function right
> there outside of the jQuery object, or am I missing something?
<snip>

Not looking does tend to be quite a good way of missing things. Take a
look at JQuery source code and you find that the - bind - method (more
or less indirectly) calls a - jQuery.event.add - method. This is its
source code form the current (1.4.2) version (or at least pertinent
highlights from the code) (and re-wrapped a little to avoid it being
broken by Usenet posting):-

| jQuery.event = {
|
| // Bind an event to an element
| // Original by Dean Edwards
| add: function( elem, types, handler, data ) {
...
| var events = elemData.events = elemData.events || {},
| eventHandle = elemData.handle, eventHandle;
^^^^^^^^^^^ ^^^^^^^^^^^
I don't like the form of variable declaration statement that uses a
single - var - but spreads numerous declarations across multiple
lines, terminating each in a comma (rather than using multiple
variable declarations, terminating each line with a semicolon). I
frequently find myself miss-reading them, and so think of them as not
being particularly clear in source code terms. Above there is evidence
of this lack of clarity in the fact that - eventHandle - has been
declared twice in the same variable declaration statement. There is no
good reason for doing that (ever) and the intention cannot have been
to write the equivalent of - eventHandle = (elemData.handle,
eventHandle) - (as that would be obviously wrong given the next line
of code), so presumably this 'oddity' has resulted (and survived
(presumably many observers)) from a failure to comprehend the source
code as presented.

| if ( !eventHandle ) {
| elemData.handle = eventHandle = function() {
| // Handle the second event of a trigger and when
| // an event is called after a page has unloaded
| return typeof jQuery !== "undefined" &&
| !jQuery.event.triggered ?
| jQuery.event.handle.apply( eventHandle.elem, arguments ):
| undefined;
| };
| }
|
| // Add elem as a property of the handle function
| // This is to prevent a memory leak with non-native
| // events in IE.
| eventHandle.elem = elem;
^^^^^^^^^^^^^^^^^^^^^^^
Here the function either retrieved or created above and assigned to
the variable - eventHandle - has a property added to it with the name
'elem' and a reference to a object that is likely to be a DOM Element
assigned to it.

JQuery comments never seem to explain the more unexpected aspects of
what JQuery code does. IE has memory leak problems (or at lest older
versions of it do), but what does "non-native events" mean, and how is
this going to prevent the memory leaks?

Possibly the idea is that if the variable - elem - where referenced in
the - jQuery.event.handle.apply( ... - line above, and not nulled at
the end of this method, then there would be an obvious circular chain
of reference, which there would be. But what follows rather negates
any effort taken to avoid that circle.

|
| // Handle multiple events separated by a space
| // jQuery(...).bind("mouseover mouseout", fn);
| types = types.split(" ");
|
| var type, i = 0, namespaces;
|
| while ( (type = types[ i++ ]) ) {
...
|
| // Init the event handler queue
| if ( !handlers ) {
| handlers = events[ type ] = [];
|
| // Check for a special event handler
| // Only use addEventListener/attachEvent if the special
| // events handler returns false
| if ( !special.setup ||
| special.setup.call(
| elem, data, namespaces, eventHandle
| ) === false
| ) {
| // Bind the global event handler to the element
| if ( elem.addEventListener ) {
| elem.addEventListener( type, eventHandle, false );
|
| } else if ( elem.attachEvent ) {
| elem.attachEvent( "on" + type, eventHandle );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
And there the circle is closed. (on IE, which is where it will matter)
The (likely DOM Element) referred to by - elem - is given a reference
to the - eventHandle - function through the - attachEvent - mechanism,
while the - eventHandle - has a reference to the - elem - object
through the 'elem' property that was assigned above. That is a
circular chain of reference, established (albeit only once, but once
is enough) for each event type, for each unique - elem - passed into
the - add - method.

| }
| }
| }
...
| elem = null;
| },
...

Outside of JQuery you can do whatever you like to avoid the memory
leak-inducing circular chains of references, but JQuery creates them
for you when you use its - bind - method. Now the question is whether
JQuery cleans these circular chains of reference up on its own, or
whether you are going to have to take some remedial action to remove
bound methods; time to "slog through jQuery's code again". And if it
turns out that you have to take action yourself then maybe you don't
have to avoid creating circular chins of reference as you would have
the opportunity to break any you did create at the same time as you
set about breaking JQuery's.

Richard.

David Mark

unread,
Jul 22, 2010, 2:53:52 PM7/22/10
to
On Jul 22, 10:16 am, John G Harris <j...@nospam.demon.co.uk> wrote:
> On Thu, 22 Jul 2010 at 00:24:04, in comp.lang.javascript, David Mark
> wrote:
>
>   <snip>
>
> >ISTM that the term instances is associated with classes, of which
> >there are none in JS.
>
> 'Instance' is associated with anything that is one of many.

Yes, in general, but it has technical connotations in this context.
But you tell me as I am not an OO expert (and IIRC that is your
specialty).

> You have
> said, I seem to remember, that there are no singleton objects in JS,

So have a lot of people. :) If there are no classes, why would there
be any reason to refer to an object as a "singleton". Another way to
look at it is that they are all singletons in JS (but that will lead
to confusion for those coming from classical OO languages).

> so
> every object must be one of many somethings.

But there are no classes, so technically speaking, there's no need to
introduce the term singleton to describe them as it would imply that
there are objects that are not "singletons". See what I mean?

>
>   <snip>
>
> >I would have called it an Array object.
>
> You are using 'Array' as an adjective here.

Yes. Common practice when discussing types of built-in objects (e.g.
Object object, Number object, etc.)

> This is just a short way of
> saying that it's an object that was created by the constructor named
> Array.

Yes.

>
> Either way, the object is a member of the class of all possible such
> objects.

But you are playing loose with those terms. Technically speaking,
there are no classes in JS.

>
> >Doesn't that make more
> >sense?  Like all JS objects, it is constructed, not instantiated.
>
> I don't believe there is any substantial difference between construct
> and instantiate.

There's definitely a difference and, however minute, using them
interchangeably will only confuse people who understand classical, but
not prototype inheritance.

>
> Occasionally you might want to distinguish between construction, which
> does not include allocating space for the object, and instantiation
> which often does, as in a factory method.

I assume you referring to factory methods on the classical side. But
that would be an obscure bit compared to other differences in the
mechanics of creating objects in prototypal and classical inheritance
schemes.

David Mark

unread,
Jul 22, 2010, 3:16:55 PM7/22/10
to
On Jul 22, 1:34 pm, Richard Cornford <Rich...@litotes.demon.co.uk>
wrote:

IIRC, they use an unload listener to offset their own previous
mistakes as used to be preached by Douglas Crockford (and hopefully
he's since renounced the strategy). Of course, they'd have been much
better off avoiding (or fixing) the mistakes. :)

The idea that such listeners are unneeded (and can be very
destructive) has only just started to reach the general public (years
late as usual). As usual, jQuery's authors are at the rear of the
pack. They'll get it eventually (maybe even after reading this
thread).

Thomas 'PointedEars' Lahn

unread,
Jul 22, 2010, 6:13:24 PM7/22/10
to
David Mark wrote:

> Thomas 'PointedEars' Lahn wrote:
>> David Mark wrote:
>> > Josh Russo wrote:
>> >> David Mark wrote:
>> >> > The objects that jQuery's "$" function return are somewhat
>> >> > array-like but have nothing to do with arrays. They are simply
>> >> > Object objects (as opposed to Array objects).
>>
>> >> You are correct. I took a look again and they are creating objects
>> >> with array like properties. What I thought they were doing was adding
>> >> custom functions/methods to an array instance.
>> ^^^^^
>>
>> > There are no instances in JS. :)
>>
>> Wrong. You want to read the ECMAScript Language Specification, any
>> Edition.
>
> ISTM that the term instances is associated with classes,

No doubt about that. But not exclusively to class-based OOP.

> of which there are none in JS.

That would depend on what one understands "classes" and "JS" to be,
especially the latter.

> Of course the language used in specifications can often be confusing when
> dropped into a general discussion.

But not in this case. I am not saying that the OP was aware that they were
referring to the wrong thing by the right name (it is rather likely that
they were not, given common misconceptions about these languages); I am
saying that your statement in its absoluteness is simply wrong.

> [snip red herring]



>> The term that has been used here is only incorrect in that it should have
>> been a capital `A' at the beginning.
>
> I would have called it an Array object.

I would have a few years ago; not anymore.

> Doesn't that make more sense?

No. If we adopt the custom that for simplicity the name of the property
that refers to an object is used as the name of that object (see "window
object" aso.), then "Array object" would specify the Array constructor, a
Function instance, instead.

> Like all JS objects, it is constructed, not instantiated.

We've been over this. The term instance as used in the Specification (and I
am not talking about `instanceof') helps to differentiate between the object
created with a constructor and the constructor object itself, to begin with.
Like many other terms in the Specification. It does not make sense to
invent different terminology when the existing one suffices.


HTH

David Mark

unread,
Jul 22, 2010, 6:20:41 PM7/22/10
to
On Jul 22, 6:13 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:

> David Mark wrote:
> > Thomas 'PointedEars' Lahn wrote:
> >> David Mark wrote:
> >> > Josh Russo wrote:
> >> >> David Mark wrote:
> >> >> > The objects that jQuery's "$" function return are somewhat
> >> >> > array-like but have nothing to do with arrays.  They are simply
> >> >> > Object objects (as opposed to Array objects).
>
> >> >> You are correct. I took a look again and they are creating objects
> >> >> with array like properties. What I thought they were doing was adding
> >> >> custom functions/methods to an array instance.
> >>                                   ^^^^^
>
> >> > There are no instances in JS.  :)
>
> >> Wrong.  You want to read the ECMAScript Language Specification, any
> >> Edition.
>
> > ISTM that the term instances is associated with classes,
>
> No doubt about that.  But not exclusively to class-based OOP.

Well, as there are no classes in JS...

>
> > of which there are none in JS.
>
> That would depend on what one understands "classes" and "JS" to be,
> especially the latter.

As you likely know, I am referring to ECMAScript implementations (e.g.
JScript, JavaScript, etc.)

>
> > Of course the language used in specifications can often be confusing when
> > dropped into a general discussion.
>
> But not in this case.  I am not saying that the OP was aware that they were
> referring to the wrong thing by the right name (it is rather likely that
> they were not, given common misconceptions about these languages); I am
> saying that your statement in its absoluteness is simply wrong.

I suppose it depends on perspective.

>
> > [snip red herring]
> >> The term that has been used here is only incorrect in that it should have
> >> been a capital `A' at the beginning.
>
> > I would have called it an Array object.
>
> I would have a few years ago; not anymore.
>
> > Doesn't that make more sense?
>
> No.  If we adopt the custom that for simplicity the name of the property
> that refers to an object is used as the name of that object (see "window
> object" aso.), then "Array object" would specify the Array constructor, a
> Function instance, instead.

Interesting twist, but when I say "window object", I am referring to
the object. The fact that it is referenced by a property of the
Global Object doesn't really enter into it.

>
> > Like all JS objects, it is constructed, not instantiated.
>
> We've been over this.  The term instance as used in the Specification (and I
> am not talking about `instanceof') helps to differentiate between the object
> created with a constructor and the constructor object itself, to begin with.  

Yes, I suppose it is more concise than saying the "constructed
object", but still the term "instance" is part of what leads to
confusion among those who are used to class-based languages.


> Like many other terms in the Specification.  It does not make sense to
> invent different terminology when the existing one suffices.

Who's inventing?

Richard Cornford

unread,
Jul 22, 2010, 6:52:12 PM7/22/10
to
David Mark wrote:

> On Jul 22, 1:34 pm, Richard Cornford wrote:
>>> On Jul 22, 9:50 am, David Mark wrote:
<snip>

>>>> That's right, you will have to slog through jQuery's code
>>>> again to determine whether it is minding its business with
>>>> regard to avoiding circular references. What your code does
>>>> is actually immaterial. Confusing and time-consuming isn't it?
<snip>

>> Outside of JQuery you can do whatever you like to avoid the
>> memory leak-inducing circular chains of references, but JQuery
>> creates them for you when you use its - bind - method. Now the
>> question is whether JQuery cleans these circular chains of
>> reference up on its own, or whether you are going to have to
>> take some remedial action to remove bound methods; time to "slog
>> through jQuery's code again". And if it turns out that you have
>> to take action yourself then maybe you don't have to avoid
>> creating circular chins of reference as you would have
>> the opportunity to break any you did create at the same
>> time as you set about breaking JQuery's.
>>
>
> IIRC, they use an unload listener to offset their own previous
> mistakes as used to be preached by Douglas Crockford (and
> hopefully he's since renounced the strategy). Of course, they'd
> have been much better off avoiding (or fixing) the mistakes. :)

If you want someone to experience the 'joys' of searching through the
sauce code of a highly interdependent javascript library in order to
find a definitive answer to a specific question then it does not seem
like a good idea to tell then the answer before hand.

Unload handlers address some of the issues but they leave the question
of what happens in the meanwhile. If an unbroken circular chain of
references is going to prevent garbage collection until the browser is
shut down, effected DOM elements that are removed/freed/replaced are not
going to be garbage collected themselves in the meanwhile. This would
become an issue in the 'single page' style of web application, where you
are expected to use the application for some time before unloading it.
Quite a few DOM Elements, some with event handlers, are likely to be
cycled through the DOM, and normally once they are finished with the
desire would be to have the objects garbage collected (especially as IE
6's performance drops off as its memory consumption increases). An
unload handler based approach is not sufficiently proactive as to
achieve that.

> The idea that such listeners are unneeded (and can be very
> destructive) has only just started to reach the general public
> (years late as usual). As usual, jQuery's authors are at the
> rear of the pack. They'll get it eventually (maybe even after
> reading this thread).

The memory leak issues are reducing with the passage of time. Even IE 6
appears to have had updates that reduce the scope of the problem. We may
not be that far away from the end of whole circular reference issue, and
so be able to stop worrying about this entirely.

Richard.

David Mark

unread,
Jul 22, 2010, 6:59:15 PM7/22/10
to
On Jul 22, 6:52 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:

Fair enough.

>
> Unload handlers address some of the issues but they leave the question
> of what happens in the meanwhile. If an unbroken circular chain of
> references is going to prevent garbage collection until the browser is
> shut down, effected DOM elements that are removed/freed/replaced are not
> going to be garbage collected themselves in the meanwhile. This would
> become an issue in the 'single page' style of web application, where you
> are expected to use the application for some time before unloading it.
> Quite a few DOM Elements, some with event handlers, are likely to be
> cycled through the DOM, and normally once they are finished with the
> desire would be to have the objects garbage collected (especially as IE
> 6's performance drops off as its memory consumption increases). An
> unload handler based approach is not sufficiently proactive as to
> achieve that.

Right. Hence the myriad mystical incantations out there (e.g. trying
to force IE to collect garbage using a method that has been
demonstrated to be useless).

>
> > The idea that such listeners are unneeded (and can be very
> > destructive) has only just started to reach the general public
> > (years late as usual).  As usual, jQuery's authors are at the
> > rear of the pack.  They'll get it eventually (maybe even after
> > reading this thread).
>
> The memory leak issues are reducing with the passage of time. Even IE 6
> appears to have had updates that reduce the scope of the problem. We may
> not be that far away from the end of whole circular reference issue, and
> so be able to stop worrying about this entirely.
>

Suits me. And isn't that always the way that the various libraries
"solve" problems? In other words, waiting for them to expire and then
removing their stacked up (and botched) attempts at solutions. No
wonder they want to "ban" IE6. :)

John G Harris

unread,
Jul 23, 2010, 3:34:41 PM7/23/10
to
On Thu, 22 Jul 2010 at 11:53:52, in comp.lang.javascript, David Mark
wrote:

<snip>


>> Either way, the object is a member of the class of all possible such
>> objects.
>
>But you are playing loose with those terms. Technically speaking,
>there are no classes in JS.

<snip>

I'm using 'class' in the same way as Bertrand Russell (he of Principia
Mathematica), and a lot of modern maths textbooks, and a lot of
philosophy textbooks. Just because some OO authors picked up the term
and ran away with it, often spouting nonsense, doesn't stop us using the
normal meaning. Especially in a language that has no class definitions.

John
--
John Harris

David Mark

unread,
Jul 23, 2010, 4:23:54 PM7/23/10
to

You don't think using "class" to debscribe objects created in a class-
free language will lead to confusion?

Garrett Smith

unread,
Jul 25, 2010, 10:29:17 PM7/25/10
to
On 2010-07-22 10:34 AM, Richard Cornford wrote:
> On Jul 22, 2:48 pm, Josh Russo wrote:
>> On Jul 22, 9:50 am, David Mark wrote:
>>> On Jul 22, 5:08 am, Josh Russo wrote:
> <snip>
[...]

>
> | if ( !eventHandle ) {
> | elemData.handle = eventHandle = function() {
> | // Handle the second event of a trigger and when
> | // an event is called after a page has unloaded
> | return typeof jQuery !== "undefined"&&
> | !jQuery.event.triggered ?
> | jQuery.event.handle.apply( eventHandle.elem, arguments ):
> | undefined;
> | };
> | }
> |
> | // Add elem as a property of the handle function
> | // This is to prevent a memory leak with non-native
> | // events in IE.
> | eventHandle.elem = elem;
> ^^^^^^^^^^^^^^^^^^^^^^^
> Here the function either retrieved or created above and assigned to
> the variable - eventHandle - has a property added to it with the name
> 'elem' and a reference to a object that is likely to be a DOM Element
> assigned to it.
>
> JQuery comments never seem to explain the more unexpected aspects of
> what JQuery code does. IE has memory leak problems (or at lest older
> versions of it do), but what does "non-native events" mean, and how is
> this going to prevent the memory leaks?
>

The `elem` property could be used in `call` to resolve context to `elem`
and could deleted later in the "remove" method.

| function getBoundCallback(o, cb) {
| // no binding for window, because:
| // 1) context is already global and
| // 2) removing onunload handlers is skipped (see cleanUp);
| if (o === window)
| return cb;
| function bound(ev) {
| bound.original.call(bound.context, ev || window.event);
| }
| bound.original = cb;
| bound.context = o;
| cb = o = null;
| return bound;
| }

And in the `remove` method, I call removeFromCallstack which deletes the
properties `context` `original` from the `bound` method.

| function removeFromCallStack(callStack, callback) {
| var cb, i, len;
| for (i = 0, len = callStack.length; i < len; i++) {
| cb = callStack[i];
| if ((cb.original || cb) === callback) {
| delete cb.original;
| delete cb.context;
| return callStack.splice(i, 1)[0];
| }
| }
| return null;
| }

> Possibly the idea is that if the variable - elem - where referenced in
> the - jQuery.event.handle.apply( ... - line above, and not nulled at
> the end of this method, then there would be an obvious circular chain
> of reference, which there would be. But what follows rather negates
> any effort taken to avoid that circle.
>

Right, they null it, and then save the reference to `elem` as a property
to the function, creating a circular reference.

The chain can be broken by deleting the `elem` property in the remove
method.

[...]

>
> Outside of JQuery you can do whatever you like to avoid the memory
> leak-inducing circular chains of references, but JQuery creates them
> for you when you use its - bind - method. Now the question is whether
> JQuery cleans these circular chains of reference up on its own, or
> whether you are going to have to take some remedial action to remove
> bound methods; time to "slog through jQuery's code again".

I see near the bottom of `remove`:
| if ( jQuery.isEmptyObject( events ) ) {
| var handle = elemData.handle;
| if ( handle ) {
| handle.elem = null;
| }
--
Garrett

David Mark

unread,
Jul 25, 2010, 10:40:57 PM7/25/10
to

The chain will be broken on remove anyway. You have to handle the
case where the application does not remove the listeners.

The proper solution is: don't create such circular references in the
first place. That's what I went with.

Garrett Smith

unread,
Jul 26, 2010, 1:34:45 AM7/26/10
to
On 2010-07-25 07:40 PM, David Mark wrote:
> On Jul 25, 10:29 pm, Garrett Smith<dhtmlkitc...@gmail.com> wrote:
>> On 2010-07-22 10:34 AM, Richard Cornford wrote:> On Jul 22, 2:48 pm, Josh Russo wrote:
>>>> On Jul 22, 9:50 am, David Mark wrote:
>>>>> On Jul 22, 5:08 am, Josh Russo wrote:
[...]

> The chain will be broken on remove anyway. You have to handle the
> case where the application does not remove the listeners.
>
It's the developer's job to remove event handlers if needed.

Another approach is to take advantage of event delegation and to design
widgets that do not keep references to elements that may be removed.
--
Garrett

David Mark

unread,
Jul 26, 2010, 1:42:09 AM7/26/10
to
On Jul 26, 1:34 am, Garrett Smith <dhtmlkitc...@gmail.com> wrote:
> On 2010-07-25 07:40 PM, David Mark wrote:> On Jul 25, 10:29 pm, Garrett Smith<dhtmlkitc...@gmail.com>  wrote:
> >> On 2010-07-22 10:34 AM, Richard Cornford wrote:>  On Jul 22, 2:48 pm, Josh Russo wrote:
> >>>> On Jul 22, 9:50 am, David Mark wrote:
> >>>>> On Jul 22, 5:08 am, Josh Russo wrote:
> [...]
> > The chain will be broken on remove anyway.  You have to handle the
> > case where the application does not remove the listeners.
>
> It's the developer's job to remove event handlers if needed.

If needed? You mean if the developer screwed up and created circular
references involving host objects. In that case, it is the job of the
developer to clean up their mess (which they shouldn't have made in
the first place).

But in general, applications decide when they want to add/remove
listeners.

>
> Another approach is to take advantage of event delegation and to design
> widgets that do not keep references to elements that may be removed.

Just don't create circular references. How many years has it been
since I first demonstrated the pattern? I believe Kangax recently
blogged about it (explaining it in more detail) on Microsoft's Script
Junkie site. Check it out! ;)

Garrett Smith

unread,
Jul 26, 2010, 1:58:43 AM7/26/10
to
On 2010-07-25 10:42 PM, David Mark wrote:
> On Jul 26, 1:34 am, Garrett Smith<dhtmlkitc...@gmail.com> wrote:
>> On 2010-07-25 07:40 PM, David Mark wrote:> On Jul 25, 10:29 pm, Garrett Smith<dhtmlkitc...@gmail.com> wrote:
>>>> On 2010-07-22 10:34 AM, Richard Cornford wrote:> On Jul 22, 2:48 pm, Josh Russo wrote:
>>>>>> On Jul 22, 9:50 am, David Mark wrote:
>>>>>>> On Jul 22, 5:08 am, Josh Russo wrote:
[...]
>
>>
>> Another approach is to take advantage of event delegation and to design
>> widgets that do not keep references to elements that may be removed.
>
> Just don't create circular references.
That phrase is superfluous (and trite) to what was explained.
--
Garrett

David Mark

unread,
Jul 26, 2010, 8:34:01 AM7/26/10
to

On the contrary, combined with my many previous examples and
explanations, it's the proverbial key to the kingdom. You solve the
problem by avoiding it. You don't like it because you didn't think of
it first. :)

Thomas 'PointedEars' Lahn

unread,
Jul 26, 2010, 9:18:05 PM7/26/10
to
David Mark wrote:

> Thomas 'PointedEars' Lahn wrote:
>> David Mark wrote:
>> > Thomas 'PointedEars' Lahn wrote:
>> >> David Mark wrote:
>> >> > Josh Russo wrote:
>> >> >> David Mark wrote:
>> >> >> > The objects that jQuery's "$" function return are somewhat
>> >> >> > array-like but have nothing to do with arrays. They are simply
>> >> >> > Object objects (as opposed to Array objects).
>> >> >> You are correct. I took a look again and they are creating objects
>> >> >> with array like properties. What I thought they were doing was
>> >> >> adding custom functions/methods to an array instance.
>> >> ^^^^^
>> >> > There are no instances in JS. :)
>> >>
>> >> Wrong. You want to read the ECMAScript Language Specification, any
>> >> Edition.
>>
>> > ISTM that the term instances is associated with classes,
>>
>> No doubt about that. But not exclusively to class-based OOP.
>
> Well, as there are no classes in JS...

Given your clarification below, you are clearly wrong.



>> > of which there are none in JS.
>> That would depend on what one understands "classes" and "JS" to be,
>> especially the latter.
>
> As you likely know, I am referring to ECMAScript implementations (e.g.
> JScript, JavaScript, etc.)

JavaScript 2.0 is an ECMAScript implementation, and it has classes (though
by contrast I do not know if it is productively used).

JScript 7.0 and above are ECMAScript implementations, and they have classes.

ActionScript 2.0 and above are ECMAScript implementations, and they have
classes.

Do I need to go on?

>> > Of course the language used in specifications can often be confusing
>> > when dropped into a general discussion.
>>
>> But not in this case. I am not saying that the OP was aware that they
>> were referring to the wrong thing by the right name (it is rather likely
>> that they were not, given common misconceptions about these languages); I
>> am saying that your statement in its absoluteness is simply wrong.
>
> I suppose it depends on perspective.

I would submit that it depends instead on whether one wants to be consistent
or not. Either we accept the terminology as provided by the Specification,
or we do not. The consensus appears to be that we accept it, so we really
should accept *all* of it.

>> > [snip red herring]
>> >> The term that has been used here is only incorrect in that it should
>> >> have been a capital `A' at the beginning.
>>
>> > I would have called it an Array object.
>>
>> I would have a few years ago; not anymore.
>>
>> > Doesn't that make more sense?
>>
>> No. If we adopt the custom that for simplicity the name of the property
>> that refers to an object is used as the name of that object (see "window
>> object" aso.), then "Array object" would specify the Array constructor, a
>> Function instance, instead.
>
> Interesting twist, but when I say "window object", I am referring to
> the object. The fact that it is referenced by a property of the
> Global Object doesn't really enter into it.

And if you say "Function object" you are not referring to that object
referred to by the identifier? How is one supposed to know the difference?
This approach leads into chaos.

>> > Like all JS objects, it is constructed, not instantiated.
>> We've been over this. The term instance as used in the Specification
>> (and I am not talking about `instanceof') helps to differentiate between
>> the object created with a constructor and the constructor object itself,
>> to begin with.
>
> Yes, I suppose it is more concise than saying the "constructed
> object", but still the term "instance" is part of what leads to
> confusion among those who are used to class-based languages.

So do other terms; yours is not a sound argument.

>> Like many other terms in the Specification. It does not make sense to
>> invent different terminology when the existing one suffices.
>
> Who's inventing?

You, or rather all of us did, until closer inspection of the Specification
showed `instance' to be a rather well-defined term (beyond `instanceof').


PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:160

David Mark

unread,
Jul 26, 2010, 9:33:07 PM7/26/10
to
On Jul 26, 9:18 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>

wrote:
> David Mark wrote:
> > Thomas 'PointedEars' Lahn wrote:
> >> David Mark wrote:
> >> > Thomas 'PointedEars' Lahn wrote:
> >> >> David Mark wrote:
> >> >> > Josh Russo wrote:
> >> >> >> David Mark wrote:
> >> >> >> > The objects that jQuery's "$" function return are somewhat
> >> >> >> > array-like but have nothing to do with arrays.  They are simply
> >> >> >> > Object objects (as opposed to Array objects).
> >> >> >> You are correct. I took a look again and they are creating objects
> >> >> >> with array like properties. What I thought they were doing was
> >> >> >> adding custom functions/methods to an array instance.
> >> >>                                          ^^^^^
> >> >> > There are no instances in JS.  :)
>
> >> >> Wrong.  You want to read the ECMAScript Language Specification, any
> >> >> Edition.
>
> >> > ISTM that the term instances is associated with classes,
>
> >> No doubt about that.  But not exclusively to class-based OOP.
>
> > Well, as there are no classes in JS...
>
> Given your clarification below, you are clearly wrong.

I doubt it.

>
> >> > of which there are none in JS.
> >> That would depend on what one understands "classes" and "JS" to be,
> >> especially the latter.
>
> > As you likely know, I am referring to ECMAScript implementations (e.g.
> > JScript, JavaScript, etc.)
>
> JavaScript 2.0 is an ECMAScript implementation, and it has classes (though
> by contrast I do not know if it is productively used).

That one's obviously irrelevant.

>
> JScript 7.0 and above are ECMAScript implementations, and they have classes.

That's JScript.NET, which is an implementation of JScript. Denied as
irrelevant. You know full well what ECMAScript implementations I am
referring to (the ones that are the subject at hand here 99.9% of the
time and typically used to script browsers).

>
> ActionScript 2.0 and above are ECMAScript implementations, and they have
> classes.

You are reaching. Do you really think I was including ActionScript in
my (abbreviated) list?

>
> Do I need to go on?

Certainly not.

>
> >> > Of course the language used in specifications can often be confusing
> >> > when dropped into a general discussion.
>
> >> But not in this case.  I am not saying that the OP was aware that they
> >> were referring to the wrong thing by the right name (it is rather likely
> >> that they were not, given common misconceptions about these languages); I
> >> am saying that your statement in its absoluteness is simply wrong.
>
> > I suppose it depends on perspective.
>
> I would submit that it depends instead on whether one wants to be consistent
> or not.  Either we accept the terminology as provided by the Specification,
> or we do not.

What part of the ECMAScript specs talks about classes?

> The consensus appears to be that we accept it, so we really
> should accept *all* of it.
>
>
>
> >> > [snip red herring]
> >> >> The term that has been used here is only incorrect in that it should
> >> >> have been a capital `A' at the beginning.
>
> >> > I would have called it an Array object.
>
> >> I would have a few years ago; not anymore.
>
> >> > Doesn't that make more sense?
>
> >> No.  If we adopt the custom that for simplicity the name of the property
> >> that refers to an object is used as the name of that object (see "window
> >> object" aso.), then "Array object" would specify the Array constructor, a
> >> Function instance, instead.
>
> > Interesting twist, but when I say "window object", I am referring to
> > the object.  The fact that it is referenced by a property of the
> > Global Object doesn't really enter into it.
>
> And if you say "Function object" you are not referring to that object
> referred to by the identifier?

No. That's the Function constructor (or Function function if you want
to be really clever).

> How is one supposed to know the difference?

Different words?

> This approach leads into chaos.

Settle down.

>
> >> > Like all JS objects, it is constructed, not instantiated.
> >> We've been over this.  The term instance as used in the Specification
> >> (and I am not talking about `instanceof') helps to differentiate between
> >> the object created with a constructor and the constructor object itself,
> >> to begin with.
>
> > Yes, I suppose it is more concise than saying the "constructed
> > object", but still the term "instance" is part of what leads to
> > confusion among those who are used to class-based languages.
>
> So do other terms; yours is not a sound argument.

I'm afraid it is.

>
> >> Like many other terms in the Specification.  It does not make sense to
> >> invent different terminology when the existing one suffices.
>
> > Who's inventing?
>
> You, or rather all of us did, until closer inspection of the Specification
> showed `instance' to be a rather well-defined term (beyond `instanceof').
>

You don't seem to get that some of the language in the specification
(which is aimed at implementors, not users) does not translate well
into general parlance. For example, the DOM specifications (aimed at
browser developers) refers to DOM properties as "attributes" in many
cases. That doesn't mean we should all start calling attributse
properties (or vice versa). I mean, look what happened to jQuery. :)

Thomas 'PointedEars' Lahn

unread,
Jul 28, 2010, 9:03:05 AM7/28/10
to
David Mark wrote:

> Thomas 'PointedEars' Lahn wrote:
>> David Mark wrote:
>> > Thomas 'PointedEars' Lahn wrote:
>> >> David Mark wrote:
>> >> > Thomas 'PointedEars' Lahn wrote:
>> >> >> David Mark wrote:
>> >> >> > Josh Russo wrote:
>> >> >> >> David Mark wrote:
>> >> >> >> > The objects that jQuery's "$" function return are somewhat
>> >> >> >> > array-like but have nothing to do with arrays. They are
>> >> >> >> > simply Object objects (as opposed to Array objects).
>> >> >> >> You are correct. I took a look again and they are creating
>> >> >> >> objects with array like properties. What I thought they were
>> >> >> >> doing was adding custom functions/methods to an array instance.
>> >> >> ^^^^^
>> >> >> > There are no instances in JS. :)
>> >> >>
>> >> >> Wrong. You want to read the ECMAScript Language Specification, any
>> >> >> Edition.
>>
>> >> > ISTM that the term instances is associated with classes,
>>
>> >> No doubt about that. But not exclusively to class-based OOP.
>>
>> > Well, as there are no classes in JS...
>>
>> Given your clarification below, you are clearly wrong.
>
> I doubt it.

Doubt as much as you want, it's a fact:

>> >> > of which there are none in JS.

^^


>> >> That would depend on what one understands "classes" and "JS" to be,
>> >> especially the latter.
>>
>> > As you likely know, I am referring to ECMAScript implementations (e.g.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> > JScript, JavaScript, etc.)
^^^^^^^^^^^^^^^^^^^^^^^^^


>> JavaScript 2.0 is an ECMAScript implementation, and it has classes
>> (though by contrast I do not know if it is productively used).
>
> That one's obviously irrelevant.

We'll see.

>> JScript 7.0 and above are ECMAScript implementations, and they have
>> classes.
>
> That's JScript.NET, which is an implementation of JScript.

Utter nonsense.

>> ActionScript 2.0 and above are ECMAScript implementations, and they have
>> classes.
>
> You are reaching.

Not at all. I am pointing out the flaw in your overgeneralization.

> Do you really think I was including ActionScript in my (abbreviated) list?

*You* have defined "JS" to be a synonym for "ECMAScript implementations"
when referring to "JS" having no classes; ActionScript is one of them, and
it certainly has classes.

>> Do I need to go on?
>
> Certainly not.

So you see the error of your way?

>> >> > Of course the language used in specifications can often be confusing
>> >> > when dropped into a general discussion.
>>
>> >> But not in this case. I am not saying that the OP was aware that they
>> >> were referring to the wrong thing by the right name (it is rather
>> >> likely that they were not, given common misconceptions about these
>> >> languages); I am saying that your statement in its absoluteness is
>> >> simply wrong.
>>
>> > I suppose it depends on perspective.
>>
>> I would submit that it depends instead on whether one wants to be
>> consistent or not. Either we accept the terminology as provided by the
>> Specification, or we do not.
>
> What part of the ECMAScript specs talks about classes?

Since you are asking, all sections of the proposal for ECMAScript Edition 4,
of which JScript 7.0+ and other languages are implementations of (despite
the fact that it never became a standard to date).

But that is beside the point. A number of sections in ECMAScript Edition 3
and 5 talk about _instances_, which was what I was referring to.

>> >> No. If we adopt the custom that for simplicity the name of the
>> >> property that refers to an object is used as the name of that object
>> >> (see "window object" aso.), then "Array object" would specify the
>> >> Array constructor, a Function instance, instead.
>> >
>> > Interesting twist, but when I say "window object", I am referring to
>> > the object. The fact that it is referenced by a property of the
>> > Global Object doesn't really enter into it.
>>
>> And if you say "Function object" you are not referring to that object
>> referred to by the identifier?
>
> No. That's the Function constructor (or Function function if you want
> to be really clever).

You may want to check on the use of either term.



>> How is one supposed to know the difference?
>
> Different words?

"Function object" is used with two meanings. This is to be avoided.
Further, you cannot reasonably use "constructor" where there is no
constructor, but still an inheritance-related name-based relationship
between one object and another.



>> This approach leads into chaos.
>
> Settle down.

Think twice.

>> >> > Like all JS objects, it is constructed, not instantiated.
>> >> We've been over this. The term instance as used in the Specification
>> >> (and I am not talking about `instanceof') helps to differentiate
>> >> between the object created with a constructor and the constructor
>> >> object itself, to begin with.
>> > Yes, I suppose it is more concise than saying the "constructed
>> > object", but still the term "instance" is part of what leads to
>> > confusion among those who are used to class-based languages.
>> So do other terms; yours is not a sound argument.
>
> I'm afraid it is.

Stomping your foot will not help you to be convincing.

>> >> Like many other terms in the Specification. It does not make sense to
>> >> invent different terminology when the existing one suffices.
>> > Who's inventing?
>> You, or rather all of us did, until closer inspection of the
>> Specification showed `instance' to be a rather well-defined term (beyond
>> `instanceof').
>
> You don't seem to get that some of the language in the specification
> (which is aimed at implementors, not users) does not translate well
> into general parlance.

"General parlance" does not consist only of the part that you or the
uninitiated accept of it. We have constructors, prototypes, native objects,
built-in objects, host objects, variable objects, activation objects, global
objects, aso. None of those would "translate well" to whatever imagined
"general parlance" you are talking about.

> For example, the DOM specifications [...]

… are entirely irrelevant in this case.


PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm> (404-comp.)

Thomas 'PointedEars' Lahn

unread,
Jul 28, 2010, 9:07:19 AM7/28/10
to
Gregor Kofler wrote:

> The square bracket notation is the preferred way to define array values.

… since approximately 2000 CE, when JScript (5.0) started to support it,
too.

David Mark

unread,
Jul 28, 2010, 2:52:33 PM7/28/10
to
On Jul 28, 9:03 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>

I think we've already seen, haven't we?

>
> >> JScript 7.0 and above are ECMAScript implementations, and they have
> >> classes.
>
> > That's JScript.NET, which is an implementation of JScript.
>
> Utter nonsense.

Is it? Perhaps you mean the implementation itself?

>
> >> ActionScript 2.0 and above are ECMAScript implementations, and they have
> >> classes.
>
> > You are reaching.
>
> Not at all.  I am pointing out the flaw in your overgeneralization.

I think you are wasting time.

>
> > Do you really think I was including ActionScript in my (abbreviated) list?
>
> *You* have defined "JS" to be a synonym for "ECMAScript implementations"
> when referring to "JS" having no classes; ActionScript is one of them, and
> it certainly has classes.
>
> >> Do I need to go on?
>
> > Certainly not.
>
> So you see the error of your way?

No.

>
>
>
> >> >> > Of course the language used in specifications can often be confusing
> >> >> > when dropped into a general discussion.
>
> >> >> But not in this case.  I am not saying that the OP was aware that they
> >> >> were referring to the wrong thing by the right name (it is rather
> >> >> likely that they were not, given common misconceptions about these
> >> >> languages); I am saying that your statement in its absoluteness is
> >> >> simply wrong.
>
> >> > I suppose it depends on perspective.
>
> >> I would submit that it depends instead on whether one wants to be
> >> consistent or not.  Either we accept the terminology as provided by the
> >> Specification, or we do not.
>
> > What part of the ECMAScript specs talks about classes?
>
> Since you are asking, all sections of the proposal for ECMAScript Edition 4,
> of which JScript 7.0+ and other languages are implementations of (despite
> the fact that it never became a standard to date).

See above. It's a non-starter.

>
> But that is beside the point.  A number of sections in ECMAScript Edition 3
> and 5 talk about _instances_, which was what I was referring to.

As mentioned, those specification are aimed at *implementors*, just as
the DOM specifications are aimed at *browser developers*. Do you
understand that they necessarily use terminology that may not
translate well to discussions among Web developers?

>
> >> >> No.  If we adopt the custom that for simplicity the name of the
> >> >> property that refers to an object is used as the name of that object
> >> >> (see "window object" aso.), then "Array object" would specify the
> >> >> Array constructor, a Function instance, instead.
>
> >> > Interesting twist, but when I say "window object", I am referring to
> >> > the object.  The fact that it is referenced by a property of the
> >> > Global Object doesn't really enter into it.
>
> >> And if you say "Function object" you are not referring to that object
> >> referred to by the identifier?
>
> > No.  That's the Function constructor (or Function function if you want
> > to be really clever).
>
> You may want to check on the use of either term.

What does that mean? Function is a constructor function.

>
> >> How is one supposed to know the difference?
>
> > Different words?
>
> "Function object" is used with two meanings.  This is to be avoided.

Exactly. That's why I don't use it to describe two different things.

 
> Further, you cannot reasonably use "constructor" where there is no
> constructor, but still an inheritance-related name-based relationship
> between one object and another.

I don't know what you mean by "there is no constructor" when we are
clearly talking about the Function identifier, which refers to a
constructor function.

>
> >> This approach leads into chaos.
>
> > Settle down.
>
> Think twice.

I did. I'm still right. :)

>
> >> >> > Like all JS objects, it is constructed, not instantiated.
> >> >> We've been over this.  The term instance as used in the Specification
> >> >> (and I am not talking about `instanceof') helps to differentiate
> >> >> between the object created with a constructor and the constructor
> >> >> object itself, to begin with.
> >> > Yes, I suppose it is more concise than saying the "constructed
> >> > object", but still the term "instance" is part of what leads to
> >> > confusion among those who are used to class-based languages.
> >> So do other terms; yours is not a sound argument.
>
> > I'm afraid it is.
>
> Stomping your foot will not help you to be convincing.

Implying that because you are not convinced does not mean that others
aren't. :)

>
> >> >> Like many other terms in the Specification.  It does not make sense to
> >> >> invent different terminology when the existing one suffices.
> >> > Who's inventing?
> >> You, or rather all of us did, until closer inspection of the
> >> Specification showed `instance' to be a rather well-defined term (beyond
> >> `instanceof').
>
> > You don't seem to get that some of the language in the specification
> > (which is aimed at implementors, not users) does not translate well
> > into general parlance.
>
> "General parlance" does not consist only of the part that you or the
> uninitiated accept of it.

I don't know what that means either.

> We have constructors, prototypes, native objects,
> built-in objects, host objects, variable objects, activation objects, global
> objects, aso.

Yes, those terms translate well as there is no ambiguity. And there
is but one Global Object.

> None of those would "translate well" to whatever imagined
> "general parlance" you are talking about.

Certainly they do.

>
> > For example, the DOM specifications [...]
>
> … are entirely irrelevant in this case.
>

Your motion is denied, counselor. :)

0 new messages