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

Function deleting itself (Deletable globals)

1 view
Skip to first unread message

Jon Gómez

unread,
Feb 24, 2009, 12:23:30 AM2/24/09
to

Hi,

I'm a beginner with Javascript, purely out of personal interest. I have
been studying various guides related to Javascript, although I have
mostly been interested in the specifications in ECMA 262. I recently
took a look at the Apple Javascript Coding Guidelines (2008), which
applies to WebKit, apparently:

http://developer.apple.com/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/JSCodingGuide.pdf

On page 21, it recommends that initializer functions contain code to
delete themselves:

---
var foo = function() {
// code that makes this function work
delete foo;
}
window.addEventListener('load', foo, false);
---

For whatever reason, I was surprised.

I immediately wondered if this were portable, safe, etc. Although it is
taken from an Apple document, I was curious if it worked with various
implementations of Javascript and what EMCA had to say about this kind
of thing.

So I jumped into ECMA-262 Edition 3 as my favorite document in these
matters. I finally reached a conclusion about my first question, but it
spawned a new one.

The question is at the very bottom. The background that brought about
my question, which I hope is not erroneous, is directly below.

Background:

Presumably the code recommended by Apple would be running in a global
execution context and be associated with the global object. It uses a
variable statement, and should therefore receive the DontDelete
attribute (ECMA-262 Edition 3, sections 12.2 and 10.2.1).

When the delete operator is used on the function, then it should call
the internal method [[Delete]] on the global object with the function as
the property (ibid. 10.2.1, 11.4.1).

Since it has the DontDelete attribute set, [[Delete]] should not remove
the property from the global object (ibid. 8.6.2.5), as a constraint on
whatever the implementation really is (c.f. ibid. 8.6.2).

In other words, "delete foo;" should not do anything, at least if the
interpreter followed the EMCAScript standard. I admit this is not
something to count on, and apparently the Apple guide counted on
something quite different.

So I ran a test on Firefox 3.0.6 using Firebug.

var obj2 = function () {
var r;
console.log("O2: " + obj2);
r = delete obj2;
console.log(r);
}

It failed to delete it, as expected. Then I learned that it does delete
it when the first "var" is removed, going on to log the result (to
Firebug console) on the next line.

Question:

Without the "var", function object instantiation is different, at least
under Firefox. I decided to look for any related behaviour as described
in EMCA-262. Well, without the var, "obj2 = function() { ... }" doesn't
seem to be a variable declaration statement. It seems to fall under the
general assignment expression (ibid. 11.13). If so, then it may be that
the DontDelete attribute setting for global properties is bypassed. It
also falls under general function declarations (ibid. 13). There is a
statement to the effect that attributes for functions are supposedly
based on the type of code (ibid. 10.1.3), but there doesn't seem to be a
clear indication of how to determine them, nor much detail in the
section describing function declaration. The types of code are listed:
global, eval, and function (ibid. 10.1.2).

Is there somewhere in the EMCA text where it clearly lays out
expectations along these lines? It seems like Firefox takes the view
that the equivalent of DontDelete shouldn't be placed upon this kind of
expression.

Thanks for putting time into reading all that. If you choose to correct
any of my errors, or answer my question, then thanks for that, as well.

Jon.

Garrett Smith

unread,
Feb 24, 2009, 1:47:43 AM2/24/09
to
Jon Gómez wrote:
> Hi,
>
> I'm a beginner with Javascript, purely out of personal interest. I have
> been studying various guides related to Javascript, although I have
> mostly been interested in the specifications in ECMA 262. I recently
> took a look at the Apple Javascript Coding Guidelines (2008), which
> applies to WebKit, apparently:
>
> http://developer.apple.com/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/JSCodingGuide.pdf
>

That document looks very official. A PDF from Apple.

> On page 21, it recommends that initializer functions contain code to
> delete themselves:
>
> ---
> var foo = function() {
> // code that makes this function work
> delete foo;
> }
> window.addEventListener('load', foo, false);
> ---
>
> For whatever reason, I was surprised.
>

You're not the only one.

> I immediately wondered if this were portable, safe, etc. Although it is
> taken from an Apple document, I was curious if it worked with various
> implementations of Javascript and what EMCA had to say about this kind
> of thing.

Good call.

Your analysis and research is good except for one very simple problem
(which I will mention below).

You realized that an assignment without var is not a variable declaration.

foo = 1;

The identifier foo must be resolved up the scope chain (see 11.13.1
Simple Assignment, also below). If foo is not found, a foo property is
created on the global object (see 8.7.2 PutValue).

| 11.13.1 Simple Assignment (= )
| The production AssignmentExpression : LeftHandSideExpression =
| AssignmentExpression is evaluated as follows:
| 1. Evaluate LeftHandSideExpression.
| 2. Evaluate AssignmentExpression.
| 3.Call GetValue(Result(2)).
| 4.Call PutValue(Result(1), Result(3)).
| 5.Return Result(3).

Step 4 leads to PutValue(foo, 1);

| 8.7.2 PutValue(V, W)
| 1. If Type(V) is not Reference, throw a ReferenceError exception.
| 2. Call GetBase(V).
| 3. If Result(2) is null, go to step 6.
| 4. Call the [[Put]] method of Result(2), passing GetPropertyName(V)
| for the property name and W for the value.
| 5. Return.
| 6. Call the [[Put]] method for the global object, passing
| GetPropertyName(V) for the property name and W for the value.
| 7. Return.

Step 2, GetBase(v) is null, so that leads to step 6. That leads to
[[Put]](foo, 1) on the global object.

| 8.6.2.2 [[Put]](P, V)
| When the [[Put]] method of O is called with property P and value V,
| the following steps are taken:
| 1. Call the [[CanPut]] method of O with name P.
| 2. If Result(1) is false, return.
| 3. If O doesn't have a property with name P, go to step 6.
| 4. Set the value of the property to V. The attributes of the
| property are not changed.
| 5. Return.
| 6. Create a property with name P, set its value to V and give it
| empty attributes.
| 7. Return.
| Note, however, that if O is an Array object, it has a more elaborate
| [[Put]] method (15.4.5.1).

Note step 6: Create a property with name P, set its value to V and give
it empty attributes.

As you realized, global variables have the attribute DontDelete, however
global object properties (user-defined ones, at least) do not.

Garrett

--
comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >

Richard Cornford

unread,
Feb 24, 2009, 3:14:12 AM2/24/09
to
Jon Gómez wrote:
> I'm a beginner with Javascript, purely out of personal interest.
> I have been studying various guides related to Javascript,
> although I have mostly been interested in the specifications in
> ECMA 262. I recently took a look at the Apple Javascript Coding
> Guidelines (2008), which applies to WebKit, apparently:
>
> http://developer.apple.com/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/JSCodingGuide.pdf
>
> On page 21, it recommends that initializer functions contain code to
> delete themselves:

You mean where it says:-

"Release initialization functions. Code that's called once and never
used again can be deleted after its execution. For instance, deleting a
window's onload handler function releases any memory associated with the
function, like this:"

That statements is somewhere between misleading and false. Javascript is
a garbage-collected language in which function objects cannot be
(actively) 'deleted' at all. The best that can be done is to arrange
that no references to those function objects continue to exist, and
after that the garbage collector will be able to remove them (and so may
do so at some point).

> ---
> var foo = function() {
> // code that makes this function work
> delete foo;
> }
> window.addEventListener('load', foo, false);
> ---

As you noted below, the - DontDelete - attribute that the - foo -
property of the pertinent Variable object acquires as a result of the -
var - declaration will mean that the - delete foo; - statement will be
ineffective/impotent. But if the intention was to remove the reference
to the function object that was the value of - foo - then the
statement - foo = null; - would do that (regardless of the - DontDelete
attribute).

Given a simple and 'effective' alternative, it is not encouraging to see
worthless code standing in its place in documents that are intended to
be informative/educational.

> For whatever reason, I was surprised.

I am not that surprised to see it, but mostly because I have experienced
years of exposure to people who have seriously defective understanding
of how javascript's - delete - operator works. It is widely mistaken for
Java's - delete - operator, which does destroy objects that it is
applied to.

> I immediately wondered if this were portable, safe, etc.

It is both portable and "safe", it is just that is portably and safely
ineffective/pointless.

> Although it is taken from an Apple document,

That means nothing, in itself. The vast majority of 'javascript
developers' have a negligible understanding of the language they are
using, regardless of who their employers are.

> I was curious if it worked with various implementations of
> Javascript and what EMCA had to say about this kind of thing.

I am not aware of any ECMAScript implementations where it does not
"work", the - delete foo; - is as pointless and ineffective in all.

<snip>


> In other words, "delete foo;" should not do anything, at
> least if the interpreter followed the EMCAScript standard.
> I admit this is not something to count on, and apparently
> the Apple guide counted on something quite different.

That "something quite different" may well have been that nobody reading
the document would know any better than its author(s).

<snip>


> Without the "var", function object instantiation is different,
> at least under Firefox.

No, the (function) object instantiation is exactly the same. The
difference that the - var - makes is to the nature of the property to
which the reference to the (function) object is assigned.

> I decided to look for any related behaviour as described
> in EMCA-262. Well, without the var, "obj2 = function() { ... }"
> doesn't seem to be a variable declaration statement. It seems to
> fall under the general assignment expression (ibid. 11.13).

Yes, it is an assignment.

> If so, then it may be that the DontDelete attribute setting for
> global properties is bypassed.

Remember the two phase processing where 'Variable Instantiation' happens
before the evaluation of any code for any execution context. The
DontDelete attributes are applied to variables during variable
instantiation, before any code gets evaluated for the execution context.

Properties of the global object created by assignment are created during
the evaluation of code for an execution context. And much like
assignments to properties of any other javascript object, no attributes
are set at the point of assignment.

This may be called 'bypassing', but would be better considered as one of
two independent processes (Variable Instantiation and assignment)
happening at two distinct times.

> It also falls under general function declarations (ibid. 13).

Absolutely not. There are no function declarations in the code above. A
function declaration commences with the - function - keyword, and is a
unit of code that is on a par with a statement. What is shown in the
code above is a function expression, which may be a sub-unit of a
statement in javascript.

> There is a statement to the effect that attributes for
> functions are supposedly based on the type of code
> (ibid. 10.1.3), but there doesn't seem to be a clear indication
> of how to determine them,

Function declarations get the same attributes (on the named properties
of the Variable object) as variables declared with - var - (and function
formal parameters). There are no variable declarations in the code being
discussed so that is not pertinent here.

> nor much detail in the section describing function declaration.
> The types of code are listed: global, eval, and function
> (ibid. 10.1.2).
>
> Is there somewhere in the EMCA text where it clearly lays out
> expectations along these lines?

Yes, if you regard ECMA 262 as 'clear' in the first place (many would
not).

I would say you want to re-read 10.1.3 (Variable Instantiation) and
relate that to 10.2.

> It seems like Firefox takes the view that the equivalent of
> DontDelete shouldn't be placed upon this kind of expression.

<snip>

Firefox is correct, and any evidence of other behaviour in other
browsers would be evidence of an implementation bug.

Richard.

Richard Cornford

unread,
Feb 24, 2009, 3:21:47 AM2/24/09
to
Richard Cornford wrote:
> Jon Gómez wrote:
<snip>

>> There is a statement to the effect that attributes for
>> functions are supposedly based on the type of code
>> (ibid. 10.1.3), but there doesn't seem to be a clear indication
>> of how to determine them,
>
> Function declarations get the same attributes (on the named properties
> of the Variable object) as variables declared with - var - (and
> function ormal parameters). There are no variable declarations in the

> code being discussed so that is not pertinent here.
<snip>

That should have been "There are no function declarations in the code
being discussed ...".

Richard.

Jon Gómez

unread,
Feb 24, 2009, 12:53:30 PM2/24/09
to

[...]

>> For whatever reason, I was surprised.
>>
>
> You're not the only one.

Good to know.


[...]


> Your analysis and research is good except for one very simple problem
> (which I will mention below).

Thanks for checking it.

Wow.

That is quite interesting! It very nicely answers my question. Thank
you for demonstrating the entire chain.

Firefox and I should be playing with these things some more, with this
new insight.

Jon.

Jon Gómez

unread,
Feb 24, 2009, 1:36:39 PM2/24/09
to
Richard Cornford wrote:
> Jon Gómez wrote:
>> I'm a beginner with Javascript, purely out of personal interest.
>> I have been studying various guides related to Javascript,
>> although I have mostly been interested in the specifications in
>> ECMA 262. I recently took a look at the Apple Javascript Coding
>> Guidelines (2008), which applies to WebKit, apparently:
>>
>> http://developer.apple.com/documentation/ScriptingAutomation/Conceptual/JSCodingGuide/JSCodingGuide.pdf
>>
>>
>> On page 21, it recommends that initializer functions contain code to
>> delete themselves:
>
> You mean where it says:-
>
> "Release initialization functions. Code that's called once and never
> used again can be deleted after its execution. For instance, deleting a
> window's onload handler function releases any memory associated with the
> function, like this:"
>
> That statements is somewhere between misleading and false. Javascript is
> a garbage-collected language in which function objects cannot be
> (actively) 'deleted' at all. The best that can be done is to arrange
> that no references to those function objects continue to exist, and
> after that the garbage collector will be able to remove them (and so may
> do so at some point).
>

Yeah, I didn't realize that at first, until I started reading up on it.
I had actually originally envisioned things like an interpreter trying
to execute non-existing code because I wrongly thought delete might be
able to just nuke the memory directly. It is definitely misleading.

>> ---
>> var foo = function() {
>> // code that makes this function work
>> delete foo;
>> }
>> window.addEventListener('load', foo, false);
>> ---
>
> As you noted below, the - DontDelete - attribute that the - foo -
> property of the pertinent Variable object acquires as a result of the -
> var - declaration will mean that the - delete foo; - statement will be
> ineffective/impotent. But if the intention was to remove the reference
> to the function object that was the value of - foo - then the statement
> - foo = null; - would do that (regardless of the - DontDelete attribute).
>
> Given a simple and 'effective' alternative, it is not encouraging to see
> worthless code standing in its place in documents that are intended to
> be informative/educational.

Hmmm... that is an interesting point. The function object is no longer
associated with the property and the reference is gone, which is the
real goal anyway.

This is a minor detail, but I guess the property (now set to null)
supposedly still has the DontDelete attribute, judging from [[Put]] step
4 in Garrett's post? Of course, that makes no difference to what
happens to the function. (In my FF test, delete returns false for the
null-valued property).


>> For whatever reason, I was surprised.
>
> I am not that surprised to see it, but mostly because I have experienced
> years of exposure to people who have seriously defective understanding
> of how javascript's - delete - operator works. It is widely mistaken for
> Java's - delete - operator, which does destroy objects that it is
> applied to.

Java's delete operator? I'm assuming you meant C++.


>> I immediately wondered if this were portable, safe, etc.
>
> It is both portable and "safe", it is just that is portably and safely
> ineffective/pointless.

I got a laugh from that.

>> Although it is taken from an Apple document,
>
> That means nothing, in itself. The vast majority of 'javascript
> developers' have a negligible understanding of the language they are
> using, regardless of who their employers are.

That doesn't sound good.


[snip]


>> Without the "var", function object instantiation is different,
>> at least under Firefox.
>
> No, the (function) object instantiation is exactly the same. The
> difference that the - var - makes is to the nature of the property to
> which the reference to the (function) object is assigned.

Ah, I don't think I meant it like that, but it was definitely a glaring
error. Thanks for catching that.


[snip]


>> If so, then it may be that the DontDelete attribute setting for
>> global properties is bypassed.
>
> Remember the two phase processing where 'Variable Instantiation' happens
> before the evaluation of any code for any execution context. The
> DontDelete attributes are applied to variables during variable
> instantiation, before any code gets evaluated for the execution context.
>
> Properties of the global object created by assignment are created during
> the evaluation of code for an execution context. And much like
> assignments to properties of any other javascript object, no attributes
> are set at the point of assignment.
>
> This may be called 'bypassing', but would be better considered as one of
> two independent processes (Variable Instantiation and assignment)
> happening at two distinct times.

Okay. That makes sense.


>> It also falls under general function declarations (ibid. 13).
>
> Absolutely not. There are no function declarations in the code above. A
> function declaration commences with the - function - keyword, and is a
> unit of code that is on a par with a statement. What is shown in the
> code above is a function expression, which may be a sub-unit of a
> statement in javascript.

Ouch, thanks for catching that! For my part, I very confusedly kept
staring at the grammar in sec. 13, and thinking, "they look the
same...", but I should have known better.


>> There is a statement to the effect that attributes for
>> functions are supposedly based on the type of code
>> (ibid. 10.1.3), but there doesn't seem to be a clear indication
>> of how to determine them,
>
> Function declarations get the same attributes (on the named properties
> of the Variable object) as variables declared with - var - (and function
> formal parameters). There are no variable declarations in the code being
> discussed so that is not pertinent here.

(Incorporating your second post/correction).

Ah. Alright, I'll study that some more.


>> nor much detail in the section describing function declaration.
>> The types of code are listed: global, eval, and function
>> (ibid. 10.1.2).
>>
>> Is there somewhere in the EMCA text where it clearly lays out
>> expectations along these lines?
>
> Yes, if you regard ECMA 262 as 'clear' in the first place (many would not).

I like reading it because it makes me think about things differently,
but it certainly is not a clear document. I almost quipped that it was
"my favorite document to shake a fist at" because it can be a struggle.


> I would say you want to re-read 10.1.3 (Variable Instantiation) and
> relate that to 10.2.

Okay. I'll be going over it again. Garret's reply helped a lot with
assignments, but I realize I need to re-read those sections too.


>> It seems like Firefox takes the view that the equivalent of
>> DontDelete shouldn't be placed upon this kind of expression.
> <snip>
>
> Firefox is correct, and any evidence of other behaviour in other
> browsers would be evidence of an implementation bug.

Okay.


Thanks for the help. Thanks for the good point about setting the
reference to null, and for pointing out my mistakes, particularly some
very legitimate distinctions I was missing. Also thanks for sending me
to some relevant sections to go over again.

Jon.

Jorge

unread,
Feb 24, 2009, 8:33:05 PM2/24/09
to
On Feb 24, 6:23 am, Jon Gómez <jgo...@invalid.invalid> wrote:

> On page 21, it recommends that initializer functions contain code to
> delete themselves:
>
> ---
> var foo = function() {
> // code that makes this function work
> delete foo;
> }
> window.addEventListener('load', foo, false);
> ---
>
> For whatever reason, I was surprised.

Whoever wrote that surely meant ~ this:

element.onload= function f () {


// code that makes this function work

element.onload= undefined; //give f to the Garbage Collector...
};

--
Jorge.

David Mark

unread,
Feb 24, 2009, 10:09:14 PM2/24/09
to

It would have been better if they meant to set it to null.

kangax

unread,
Feb 24, 2009, 10:40:19 PM2/24/09
to
David Mark wrote:
[...]

> It would have been better if they meant to set it to null.

Is there a practical difference between setting it to `null` or setting
it to `undefined` (besides following conventions and, perhaps, less typing)?

--
kangax

Lasse Reichstein Nielsen

unread,
Feb 25, 2009, 1:30:19 AM2/25/09
to
Jon Gómez <jgo...@invalid.invalid> writes:

> On page 21, it recommends that initializer functions contain code to
> delete themselves:
>
> ---
> var foo = function() {
> // code that makes this function work
> delete foo;
> }
> window.addEventListener('load', foo, false);
> ---
>
> For whatever reason, I was surprised.

As others have said, this is misguided.
The first reason is that "delete foo" does nothing.
But even if it did, the window event listener would still hold a reference
to the function, so it couldn't get GC'ed (unless the implementation
clears the "load" event listeners after load, which might be a reasonable
optimization - but I don't know whether *all* browsers do so).

This also means that you can clear the "foo" variable immediately after
adding the event listener. There is no need to wait until the function
is called.


What I would do is:

window.addEventListener('load', function onload() {
// do my thing.
window.removeEventListener('load', onload, false);
}, false);

No need to create a global variable for the function at all.

/L
--
Lasse Reichstein Holst Nielsen
'Javascript frameworks is a disruptive technology'

Garrett Smith

unread,
Feb 25, 2009, 1:53:17 AM2/25/09
to
Lasse Reichstein Nielsen wrote:
> Jon Gómez <jgo...@invalid.invalid> writes:
>

>
> What I would do is:
>
> window.addEventListener('load', function onload() {
> // do my thing.
> window.removeEventListener('load', onload, false);
> }, false);
>
> No need to create a global variable for the function at all.

If supporting IE or safari 2 is unimportant, then that strategy would
seem to work.

Did you test that to make sure that the onload callback was removed?

Richard Cornford

unread,
Feb 25, 2009, 3:35:38 AM2/25/09
to
kangax wrote :

The choice of null is almost entirely convention; any primitive would do
the job (though only null and undefined could avoid being misleading).
There could be no history behind the use of undefined because it is such
a recent addition to the language (introduced in ES3). Go back four or
five years to the tail-end of IE 4 use and any reference to -
undefined - in code could be expected to result in IE4's ; "'undefined'
is undefined" error.

It is extremely rare that 'less typing' has been the reason for doing
(or not doing) anything. That is a recent excuse, and only for things
that could never be otherwise justified at all.

Richard.

Jorge

unread,
Feb 25, 2009, 6:42:04 AM2/25/09
to
On Feb 25, 9:35 am, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:

>
> The choice of null is almost entirely convention; any primitive would do
> the job

Or not-so-primitive, e.g. element.onload= Boolean; or = window.alert;
would do. Anything as long as it's !== to said f.

--
Jorge.

Thomas 'PointedEars' Lahn

unread,
Feb 25, 2009, 7:26:03 AM2/25/09
to
Lasse Reichstein Nielsen wrote:
> Jon Gómez <jgo...@invalid.invalid> writes:
>> On page 21, it recommends that initializer functions contain code to
>> delete themselves:
>>
>> ---
>> var foo = function() {
>> // code that makes this function work
>> delete foo;
>> }
>> window.addEventListener('load', foo, false);
>> ---
>>
>> For whatever reason, I was surprised.
>
> As others have said, this is misguided.
> The first reason is that "delete foo" does nothing.

That is not quite correct :) `delete foo' evaluates to `false' in this case
(in JavaScript 1.8) because the operation must fail (the property has the
DontDelete attribute):

var a = 42;

try
{
var x = delete a;
}
catch (e)
{
// not executed
window.alert("Exception: " + e);
}

// displays 42, false (in Gecko 1.9.0.6)
window.alert([a, x]);


PointedEars

Lasse Reichstein Nielsen

unread,
Feb 25, 2009, 11:50:48 AM2/25/09
to
Garrett Smith <dhtmlk...@gmail.com> writes:

> Lasse Reichstein Nielsen wrote:
>> Jon Gómez <jgo...@invalid.invalid> writes:
>>
>
>
>
>> What I would do is:
>> window.addEventListener('load', function onload() {
>> // do my thing.
>> window.removeEventListener('load', onload, false);
>> }, false);
>> No need to create a global variable for the function at all.
>
> If supporting IE or safari 2 is unimportant, then that strategy would
> seem to work.

Indeed. The original code used only addEventListener, so I stayed with
that. Doesn't work in old browsers (IE 6 included).

> Did you test that to make sure that the onload callback was removed?

No. If the event handling on the window object is the same as the one
on DOM elements, then it should work, but we are working outside the
specification here.

Also, there is no way to test it, since the load event won't fire
again, and there is no way to see which event listeners have been
registered using addEventListener. (That's why it would be a safe
optimization to throw them all away after the load event has fired).

Garrett Smith

unread,
Feb 25, 2009, 12:24:24 PM2/25/09
to
Lasse Reichstein Nielsen wrote:
> Garrett Smith <dhtmlk...@gmail.com> writes:
>
>> Lasse Reichstein Nielsen wrote:
>>> Jon Gómez <jgo...@invalid.invalid> writes:
>>>
>>
>>
>>> What I would do is:
>>> window.addEventListener('load', function onload() {
>>> // do my thing.
>>> window.removeEventListener('load', onload, false);
>>> }, false);
>>> No need to create a global variable for the function at all.
>> If supporting IE or safari 2 is unimportant, then that strategy would
>> seem to work.
>
> Indeed. The original code used only addEventListener, so I stayed with
> that. Doesn't work in old browsers (IE 6 included).
>
>> Did you test that to make sure that the onload callback was removed?
>
> No. If the event handling on the window object is the same as the one
> on DOM elements, then it should work, but we are working outside the
> specification here.
>

How so?

> Also, there is no way to test it, since the load event won't fire
> again, and there is no way to see which event listeners have been
> registered using addEventListener. (That's why it would be a safe
> optimization to throw them all away after the load event has fired).
>

The load event can be fired again by creating and dispatching an event
on the window.

Garrett Smith

unread,
Feb 25, 2009, 12:43:13 PM2/25/09
to
Garrett Smith wrote:
> Lasse Reichstein Nielsen wrote:
>> Garrett Smith <dhtmlk...@gmail.com> writes:
>>
>>> Lasse Reichstein Nielsen wrote:
>>>> Jon Gómez <jgo...@invalid.invalid> writes:

[...]


>> No. If the event handling on the window object is the same as the one
>> on DOM elements, then it should work, but we are working outside the
>> specification here.
>>
>
> How so?
>

Because it is window, not specified by the dom, that would be the
nonstandard part.

The dom does provide a load type[1]
| load
| The load event occurs when the DOM implementation finishes loading
| all content within a document, all frames within a FRAMESET, or an
| OBJECT element.
|
| * Bubbles: No
| * Cancelable: No
| * Context Info: None

But does not say that the target is window (what the event fires on).

[...]
Garrett


--
comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >

[1]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-htmlevents

Lasse Reichstein Nielsen

unread,
Feb 25, 2009, 1:14:57 PM2/25/09
to
Garrett Smith <dhtmlk...@gmail.com> writes:

>> No. If the event handling on the window object is the same as the one
>> on DOM elements, then it should work, but we are working outside the
>> specification here.
>
> How so?

The window object is not covered by the DOM 2 HTML specification, and
not part of the DOM document structure. There is no reason to expect
it to implement the DOM2 EventTarget interface.
(Even if we use "document.defaultView" instead of "window", the
document.defaultView object isn't a Node, so it doesn't have to be an
EventTarget).

Using "window.onload" is the traditional way to programmatically affect
the event handler corresponding to <body onload="...">. It would be more
consistent to place it on the document element, but tradition wins, as
always in browser scripting.

>> Also, there is no way to test it, since the load event won't fire
>> again, and there is no way to see which event listeners have been
>> registered using addEventListener. (That's why it would be a safe
>> optimization to throw them all away after the load event has fired).
>
> The load event can be fired again by creating and dispatching an event
> on the window.

True, good idea.

Opera and Firefox does remove the listener (and not other "load" event
listeners). Safari 3 doesn't support window.dispatchEvent, so I couldn't
check there. IE 7 obviously doesn't work.

Test code:

<script type="text/javascript">
window.addEventListener("load", function foo() {
alert("I RUN");
window.removeEventListener("load", foo, false);
}, false);
window.addEventListener("load", function bar() {
alert("I ALWAYS RUN");
}, false);
</script>
<input type="button" value="Again!" onclick="
try {
var evt = document.createEvent('UIEvent');
evt.initEvent('load', true, true);
window.dispatchEvent(evt);
} catch (e) {
alert(e);

Garrett Smith

unread,
Feb 25, 2009, 4:44:39 PM2/25/09
to
Lasse Reichstein Nielsen wrote:
> Garrett Smith <dhtmlk...@gmail.com> writes:
>
>>> No. If the event handling on the window object is the same as the one
>>> on DOM elements, then it should work, but we are working outside the
>>> specification here.
>> How so?
>
> The window object is not covered by the DOM 2 HTML specification, and
> not part of the DOM document structure. There is no reason to expect
> it to implement the DOM2 EventTarget interface.
> (Even if we use "document.defaultView" instead of "window", the
> document.defaultView object isn't a Node, so it doesn't have to be an
> EventTarget).
>
> Using "window.onload" is the traditional way to programmatically affect
> the event handler corresponding to <body onload="...">. It would be more
> consistent to place it on the document element, but tradition wins, as
> always in browser scripting.
>

Right. I think Mac IE 5 had document.onload. Opera has it.

>>> Also, there is no way to test it, since the load event won't fire
>>> again, and there is no way to see which event listeners have been
>>> registered using addEventListener. (That's why it would be a safe
>>> optimization to throw them all away after the load event has fired).
>> The load event can be fired again by creating and dispatching an event
>> on the window.
>
> True, good idea.
>
> Opera and Firefox does remove the listener (and not other "load" event
> listeners). Safari 3 doesn't support window.dispatchEvent, so I couldn't
> check there. IE 7 obviously doesn't work.
>

The Safari devs probably just didn't feel the need to implement that.
Creating and dispatching events is useful for testing. Of course, too
bad about IE 8. No DOM Events. I think this reflects poorly on Microsoft.


> Test code:
>
> <script type="text/javascript">
> window.addEventListener("load", function foo() {
> alert("I RUN");
> window.removeEventListener("load", foo, false);
> }, false);
> window.addEventListener("load", function bar() {
> alert("I ALWAYS RUN");
> }, false);
> </script>
> <input type="button" value="Again!" onclick="
> try {
> var evt = document.createEvent('UIEvent');
> evt.initEvent('load', true, true);
> window.dispatchEvent(evt);
> } catch (e) {
> alert(e);
> }
> ">
>
> /L

It should not be "UIEvent"[1]. I think that should be "HTMLEvents"[2].

| Note: To create an instance of the UIEvent interface, use the feature
| string "UIEvents" as the value of the input parameter used with the
| createEvent method of the DocumentEvent interface.

The plurality vs singularity can be hard to remember (HTMLEvent vs
HTMLEvents, UIEvent vs UIEvents).

Garrett

--
comp.lang.javascript FAQ <URL: http://jibbering.com/faq/ >

[1]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-uievents-h3
[2]http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-htmlevents-h3

Dr J R Stockton

unread,
Feb 25, 2009, 3:27:33 PM2/25/09
to
In comp.lang.javascript message <VsednYBStdtBnzjUnZ2dnUVZ8r2WnZ2d@gigane
ws.com>, Wed, 25 Feb 2009 08:35:38, Richard Cornford
<Ric...@litotes.demon.co.uk> posted:

>The choice of null is almost entirely convention; any primitive would
>do the job (though only null and undefined could avoid being
>misleading). There could be no history behind the use of undefined
>because it is such a recent addition to the language (introduced in
>ES3). Go back four or five years to the tail-end of IE 4 use and any
>reference to - undefined - in code could be expected to result in IE4's
>; "'undefined' is undefined" error.
>
>It is extremely rare that 'less typing' has been the reason for doing
>(or not doing) anything. That is a recent excuse, and only for things
>that could never be otherwise justified at all.

Rather than using a literal of the Undefined type, I use a variable
(commonly U, which is easy to spell) which has that value. But I don't
know whether that would be OK in ECMA < 3.

I don't recall undefined being not defined in IE 4 (Win98 1st Edn).

--
(c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Plaintext, quoting : see <URL:http://www.usenet.org.uk/ukpost.html>
Do not Mail News to me. Before a reply, quote with ">" or "> " (SoRFC1036)

0 new messages