How to ensure memory leak protection?

J

Josh Russo

Am 2010-07-22 15:48, Josh Russo meinte:




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()'.
With this attitude, you will never become a good script kiddie...

Damn! My life's dream shattered!
 
G

Gregor Kofler

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
 
R

Richard Cornford

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.
 
D

David Mark

'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?
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.
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.
 
D

David Mark

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.

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).
 
T

Thomas 'PointedEars' Lahn

David said:
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

PointedEars
 
D

David Mark

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

Well, as there are no classes 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.)
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.
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?
 
D

David Mark

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.

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 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. :)
 
J

John G Harris

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
 
D

David Mark

  <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.

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

Garrett Smith

[...]


| 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;
| 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;
| }
 
D

David Mark

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;
|     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;
|  }


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.
 
G

Garrett Smith

[...]
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.
 
D

David Mark

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! ;)
 
G

Garrett Smith

[...]
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.
 
D

David Mark

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.

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. :)
 
T

Thomas 'PointedEars' Lahn

David said:
Well, as there are no classes in JS...

Given your clarification below, you are clearly wrong.
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?
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.
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.
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
 
D

David Mark

Given your clarification below, you are clearly wrong.

I doubt it.
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.
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.
So do other terms; yours is not a sound argument.

I'm afraid it is.
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. :)
 
T

Thomas 'PointedEars' Lahn

David said:
I doubt it.

Doubt as much as you want, it's a fact:
That one's obviously irrelevant.

We'll see.
That's JScript.NET, which is an implementation of JScript.

Utter nonsense.
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.
Certainly not.

So you see the error of your way?
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. 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.
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.
Settle down.

Think twice.
I'm afraid it is.

Stomping your foot will not help you to be convincing.
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
 
T

Thomas 'PointedEars' Lahn

Gregor said:
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.


PointedEars
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,567
Members
47,202
Latest member
misc.

Latest Threads

Top