Window load/unload calling Object.prototype extension method.

Z

Zvt.Fred

Hi people,

When I extend the Object's prototype like this:

Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}

var d = new Date();
d.zvt_hello();

var i = new Number();
i.zvt_hello();

I noted that zvt_hello() method is called in window.onload and
window.onunload.
I tested on FF 3.0.8 and IE 6.0.2.

Can anyone explain me why this happens?

Thanks everyone!
Fred
 
T

Thomas 'PointedEars' Lahn

Zvt.Fred said:
When I extend the Object's prototype like this:

Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}

var d = new Date();
d.zvt_hello();

var i = new Number();
i.zvt_hello();

I noted that zvt_hello() method is called in window.onload and
window.onunload.
I tested on FF 3.0.8 and IE 6.0.2.

Can anyone explain me why this happens?

You call it there. (That was easy.)


PointedEars
 
Z

Zvt.Fred

You call it there.  (That was easy.)

When I do:

Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}

I'm also calling this function?
I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();

Can you clarify me?

Thanks a lot for your help.
Fred
 
T

Thomas 'PointedEars' Lahn

Zvt.Fred said:
When I do:

Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}

I'm also calling this function?
No.

I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
Correct.

I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();

Also correct.
Can you clarify me?

"There" means whatever you think `window.onload' or `window.unonload' is.

JFTR: The method is not called in my Firefox (Iceweasel) 3.0.6. However, it
is a Bad Idea to augment Object.prototype because all native and some host
objects inherit from it; thus augmentation there makes for-in iteration a
lot harder.

Please don't remove the attribution lines.


PointedEars
 
Z

Zvt.Fred

Also correct.


"There" means whatever you think `window.onload' or `window.unonload' is.

JFTR: The method is not called in my Firefox (Iceweasel) 3.0.6.  However, it
is a Bad Idea to augment Object.prototype because all native and some host
objects inherit from it; thus augmentation there makes for-in iteration a
lot harder.

Please don't remove the attribution lines.

PointedEars

Well, what I'm trying to understand is exactly this strange behavior.
I don't see why this method is been called on load/unload of the
window automatically. Anyway, I leave the idea of augment
Object.prototype already, but still curious about this.

Even more curious now that you said that in Iceweasel it doesn't
happen. Maybe some friend with Windows can test it for us. Just
augment Object with some dummy method and look for automatic calls in
window load/unload.

Thank you very much, PointedEars.

Fred.
 
D

David Mark

Also correct.


"There" means whatever you think `window.onload' or `window.unonload' is.

JFTR: The method is not called in my Firefox (Iceweasel) 3.0.6.  However, it
is a Bad Idea to augment Object.prototype because all native and some host
objects inherit from it; thus augmentation there makes for-in iteration a
lot harder.

Yes, it will break poorly designed scripts (like jQuery, Mootools,
etc.), which do not take into account that native object prototypes
can be augmented. This is why "mash-ups" tend to get mashed up,
ground up and are ultimately spat out.

[snip]
 
T

Thomas 'PointedEars' Lahn

David said:
Yes, it will break poorly designed scripts (like jQuery, Mootools,
etc.), which do not take into account that native object prototypes
can be augmented. This is why "mash-ups" tend to get mashed up,
ground up and are ultimately spat out.

It will break all scripts that use for-in iteration, not only poorly
designed ones. And if you are saying that for-in iteration is a bad
idea per se, we have to disagree.


PointedEars
 
G

Garrett Smith

Zvt.Fred said:
When I do:

Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}

I'm also calling this function?
I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();

Can you clarify me?

In your first post, you posted code that calls the "zvt_hello" method twice.

What makes you certain that the method was called from onload and onunload?

Changing your code slightly:-

<script type="text/javascript">
Object.prototype.zvt_hello = function() {
alert(this.constructor);
}

var d = new Date();
d.zvt_hello();
var i = new Number();
i.zvt_hello();
</script>

- results in two alerts:

function Date(){
[native code]
}

function Number(){
[native code]
}

<aside>
Those don't conform to ECMA 262r3
| 15.3.4.2 Function.prototype.toString()
|
| An implementation-dependent representation of the function is
| returned. This representation has the syntax of a FunctionDeclaration.
</aside>

Garrett
 
Z

Zvt.Fred

When I do:
         Object.prototype.zvt_hello = function() {
             alert("Hello object! (" + this.toString() + ")");
         }
I'm also calling this function?
I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();
Can you clarify me?

In your first post, you posted code that calls the "zvt_hello" method twice.

What makes you certain that the method was called from onload and onunload?

Changing your code slightly:-

<script type="text/javascript">
   Object.prototype.zvt_hello = function() {
     alert(this.constructor);
   }

   var d = new Date();
   d.zvt_hello();
   var i = new Number();
   i.zvt_hello();
</script>

- results in two alerts:

function Date(){
   [native code]

}

function Number(){
   [native code]

}

<aside>
Those don't conform to ECMA 262r3
| 15.3.4.2  Function.prototype.toString()
|
| An implementation-dependent representation of the function is
| returned. This representation has the syntax of a FunctionDeclaration.
</aside>

Garrett

I'll have to apologize with you guys for make such a noobie mistake.
In the html file that I was using to test the code that I first send
jQuery 1.3.2 was being imported and only in this situation the
zvt_hello method was called in window load/unload, though i didn't
know why since i find very hard to have a call to a method named
zvt_hello inside jQuery and doesn't make sense to me that in window
load/unload event handlers jQuery calls any extension to Object. Maybe
that kind of break that David Mark was telling about in his response.

Garrett, why you think that don't conforms to ECMA specifications?
When you call d.zvt_hello() and i.zvt_hello() your implementation was
executed but Date and Number constructor functions are alerted because
you tell to do so in alert(this.constructor).

Thanks everybody.
Fred
 
T

Timo Reitz

Zvt.Fred said:
function Date(){
[native code]
}

function Number(){
[native code]
}

<aside> Those don't conform to ECMA 262r3 | 15.3.4.2
Function.prototype.toString() | | An implementation-dependent
representation of the function is | returned. This representation has
the syntax of a FunctionDeclaration. </aside>

Garrett, why you think that don't conforms to ECMA specifications? When
you call d.zvt_hello() and i.zvt_hello() your implementation was executed
but Date and Number constructor functions are alerted because you tell to
do so in alert(this.constructor).

They don't conform to it because

function Number(){
[native code]
}

is not a valid FunctionDeclaration.
 
G

Garrett Smith

Zvt.Fred said:
In your first post, you posted code that calls the "zvt_hello" method twice.

What makes you certain that the method was called from onload and onunload?
[...]

I'll have to apologize with you guys for make such a noobie mistake.

AFAIK, this question has never come up here.
In the html file that I was using to test the code that I first send
jQuery 1.3.2 was being imported and only in this situation the
zvt_hello method was called in window load/unload, though i didn't
know why since i find very hard to have a call to a method named

You say you did not know why, but you did not state how you were certain
that this code was called in load/unload. Your example did not back up
your claim.
zvt_hello inside jQuery and doesn't make sense to me that in window

Ah, you failed to provide a test case that included jQuery! Now I'm
getting more of the picture.
load/unload event handlers jQuery calls any extension to Object. Maybe
that kind of break that David Mark was telling about in his response.

It is possible that there is a for in loop somewhere:-

for(var p in obj) {
if(jQuery.isFunction(obj(p)) {

....

I can change that test case to include jQuery and, if it is
reproducible, find exactly why.

However, before doing that, there is one question, The unload behavior
is observable by cause and effect. So the question is: What makes you
think the function was called from the window's load event?
Garrett, why you think that don't conforms to ECMA specifications?

Exactly for the reason that Timo Reitz provided. Please see the
production for FunctionDeclaration.
When you call d.zvt_hello() and i.zvt_hello() your implementation was
executed but Date and Number constructor functions are alerted because
you tell to do so in alert(this.constructor).

Thanks everybody.
Fred

Garrett
 
Z

Zvt.Fred

Zvt.Fred said:
Zvt.Fred wrote:
You call it there.  (That was easy.)
When I do:
         Object.prototype.zvt_hello = function() {
             alert("Hello object! (" + this.toString() + ")");
         }
I'm also calling this function?
I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();
Can you clarify me?
In your first post, you posted code that calls the "zvt_hello" method twice.
What makes you certain that the method was called from onload and onunload?
[...]

I'll have to apologize with you guys for make such a noobie mistake.

AFAIK, this question has never come up here.
In the html file that I was using to test the code that I first send
jQuery 1.3.2 was being imported and only in this situation the
zvt_hello method was called in window load/unload, though i didn't
know why since i find very hard to have a call to a method named

You say you did not know why, but you did not state how you were certain
that this code was called in load/unload. Your example did not back up
your claim.
zvt_hello inside jQuery and doesn't make sense to me that in window

Ah, you failed to provide a test case that included jQuery! Now I'm
getting more of the picture.
load/unload event handlers jQuery calls any extension to Object. Maybe
that kind of break that David Mark was telling about in his response.

It is possible that there is a for in loop somewhere:-

for(var p in obj) {
   if(jQuery.isFunction(obj(p)) {

...

I can change that test case to include jQuery and, if it is
reproducible, find exactly why.

However, before doing that, there is one question, The unload behavior
is observable by cause and effect. So the question is: What makes you
think the function was called from the window's load event?
Garrett, why you think that don't conforms to ECMA specifications?

Exactly for the reason that Timo Reitz provided. Please see the
production for FunctionDeclaration.
When you call d.zvt_hello() and i.zvt_hello() your implementation was
executed but Date and Number constructor functions are alerted because
you tell to do so in alert(this.constructor).
Thanks everybody.
Fred

Garrett

I'm not sure that this function was called on load/unload anymore,
when I run this html:

<html><head><title></title>
<script type="text/javascript" src="../jQuery/jquery-1.3.2.min.js" ></
script>
<script type="text/javascript">

Object.prototype.zvt_hello = function() {
alert(this.constructor);
}

var d = new Date();
d.zvt_hello();

var i = new Number();
i.zvt_hello();

</script></head><body></body></html>

I receive this alerts (in order):

In Firefox 3.0.8 In IE 6.0.2

1. [object Window] undefined

2. function Date() { function Date() {
[native code] [native code]
} }

3. function Number() { function Number() {
[native code] [native code]
} }

4. [object Window] undefined

And when I unload the page (calling another page), I receive another:

5. [object Window] undefined

However I'm sure that is a behavior caused be the insertion of jQuery
because if I remove its inclusion, I receive only the 2nd and 3rd
alerts. But I don't think this can be caused be the jQuery.isFunction
helper method since its implementation is as follows (in v.1.3.2):

(...)
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
},
(...)

And if I run toString.call(d.zvt_hello) I'll obtain "[object
Function]", not another call to that function.

Also, i continue not understanding why function() { [native code] } is
not a valid FunctionDeclaration if in ECMAScript Specs 262 r3 the
specification is as follows:

FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }

It's because of the [native code] placeholder?

Fred.
 
T

Thomas 'PointedEars' Lahn

Garrett said:
<script type="text/javascript">
Object.prototype.zvt_hello = function() {
alert(this.constructor);
}

var d = new Date();
d.zvt_hello();
var i = new Number();
i.zvt_hello();
</script>

- results in two alerts:

function Date(){
[native code]
}

function Number(){
[native code]
}

<aside>
Those don't conform to ECMA 262r3

You are mistaken because alert() is a host method (of Window objects, and
should therefore be called window.alert()). It may display anything there.


PointedEars
 
G

Garrett Smith

Zvt.Fred said:
Zvt.Fred said:
Zvt.Fred wrote:
You call it there. (That was easy.)
When I do:
Object.prototype.zvt_hello = function() {
alert("Hello object! (" + this.toString() + ")");
}
I'm also calling this function?
I think I just create a new function and assigned to property
'zvt_hello' of Object's prototype.
I'm expecting the function to be called just in d.zvt_hello(); and
i.zvt_hello();
Can you clarify me?
In your first post, you posted code that calls the "zvt_hello" method twice.
What makes you certain that the method was called from onload and onunload? [...]

I'll have to apologize with you guys for make such a noobie mistake.
AFAIK, this question has never come up here.
In the html file that I was using to test the code that I first send
jQuery 1.3.2 was being imported and only in this situation the
zvt_hello method was called in window load/unload, though i didn't
know why since i find very hard to have a call to a method named
You say you did not know why, but you did not state how you were certain
that this code was called in load/unload. Your example did not back up
your claim.
zvt_hello inside jQuery and doesn't make sense to me that in window
Ah, you failed to provide a test case that included jQuery! Now I'm
getting more of the picture.
load/unload event handlers jQuery calls any extension to Object. Maybe
that kind of break that David Mark was telling about in his response.
It is possible that there is a for in loop somewhere:-

for(var p in obj) {
if(jQuery.isFunction(obj(p)) {

...

I can change that test case to include jQuery and, if it is
reproducible, find exactly why.

However, before doing that, there is one question, The unload behavior
is observable by cause and effect. So the question is: What makes you
think the function was called from the window's load event?
Garrett, why you think that don't conforms to ECMA specifications?
Exactly for the reason that Timo Reitz provided. Please see the
production for FunctionDeclaration.
When you call d.zvt_hello() and i.zvt_hello() your implementation was
executed but Date and Number constructor functions are alerted because
you tell to do so in alert(this.constructor).
Thanks everybody.
Fred
Garrett

I'm not sure that this function was called on load/unload anymore,
when I run this html:

<html><head><title></title>
<script type="text/javascript" src="../jQuery/jquery-1.3.2.min.js" ></
script>
<script type="text/javascript">

Object.prototype.zvt_hello = function() {
alert(this.constructor);
}

var d = new Date();
d.zvt_hello();

var i = new Number();
i.zvt_hello();

</script></head><body></body></html>

I receive this alerts (in order):

In Firefox 3.0.8 In IE 6.0.2

1. [object Window] undefined

unload of previous document may have fired here.
2. function Date() { function Date() {
[native code] [native code]
} }

3. function Number() { function Number() {
[native code] [native code]
} }

Result of calling the function (your calls).
4. [object Window] undefined

load event may have fired here.
And when I unload the page (calling another page), I receive another:

5. [object Window] undefined

That could be unload.
And if I run toString.call(d.zvt_hello) I'll obtain "[object
Function]", not another call to that function.

toString being a property of the global object would be window.toString.
Calling that in context of a function would likely fail (and superficial
testing results in an error in Firefox).

Here is my new test case:-

<script type="text/javascript" src="../../jslib/jquery-1.3.2.js"></script>
<script type="text/javascript">
Object.prototype.zvt_hello = function(e) {
alert([e && e.type, arguments.callee.caller.caller].join("\n\n"));
}
</script>

Result:-
| load
|
| function () {
| return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
| jQuery.event.handle.apply(arguments.callee.elem, arguments) :
| undefined;
|
| }

(similar with unload).

Look at jQuery source: That string is an anonymous function that is
created in (and only in) the jQuery.event |add| method.

So what you stated was in fact true.

As to why jQuery adds this, lets look at the caller to jQuery.event.add:-

| jQuery.event = {
| // Bind an event to an element
| // Original by Dean Edwards
| add: function(elem, types, handler, data) {
| if ( elem.nodeType == 3 || elem.nodeType == 8 )
| return;
| // (GS) added debug alert statement.
| alert(arguments.callee.caller + "\n\n" +
| 'arguments:\n '+[].join.call(arguments, '\n ');
|

Running the example code, I see:

| fn:
| function (event) {
| jQuery(this).unbind(event, one);
| return (fn || data).apply(this, arguments);
| }

- that's jQuery.fn.one.

| fn:
| function () {
| if (!jQuery.isReady) {
| jQuery.isReady = true;
| if (jQuery.readyList) {
| jQuery.each(jQuery.readyList, function () {
| this.call(document, jQuery);});
| jQuery.readyList = null;
| }
| jQuery(document).triggerHandler("ready");
| }
| }

- that's jQuery.ready.
Also, i continue not understanding why function() { [native code] } is
not a valid FunctionDeclaration if in ECMAScript Specs 262 r3 the
specification is as follows:

FunctionDeclaration :
function Identifier ( FormalParameterListopt ) { FunctionBody }

It's because of the [native code] placeholder?

FunctionBody :
SourceElements

-->

SourceElements :
SourceElement
SourceElements SourceElement

-->

SourceElement :
Statement
FunctionDeclaration

So the content of a FunctionDeclaration must contain a Statement or a
FunctionDeclaration.
"[native code]" is not a FunctionDeclaration. Is it a statement?
Have a look:

Statement :
Block
VariableStatement
EmptyStatement
ExpressionStatement
IfStatement
IterationStatement
ContinueStatement
BreakStatement
ReturnStatement
WithStatement
LabelledStatement
SwitchStatement
ThrowStatement
TryStatement


Garrett
 
T

Thomas 'PointedEars' Lahn

David said:
Thomas said:
It will break all scripts that use for-in iteration, not only poorly
designed ones.

[snip]

Okay, I'll bite. Where are you getting that from?

Sorry, I don't follow. Maybe if you didn't snip this much you had got my
meaning?


PointedEars
 
G

Garrett Smith

Thomas said:
Garrett said:
<script type="text/javascript">
Object.prototype.zvt_hello = function() {
alert(this.constructor);
}

var d = new Date();
d.zvt_hello();
var i = new Number();
i.zvt_hello();
</script>

- results in two alerts:

function Date(){
[native code]
}

function Number(){
[native code]
}

<aside>
Those don't conform to ECMA 262r3

You are mistaken because alert() is a host method (of Window objects, and
should therefore be called window.alert()). It may display anything there.

The alert method converts its argument to a string value.

window.alert( '' + this.constructor );

would have the same effect of popping up an alert box with the [native
code] function representations.

<aside>
Although this is invalid, certain libraries actually depend on this
behavior. Dojo, Mootools, and Qooxdoo, for example perform tests to see
if the result of converting an object to a string (using its toString)
contains "[native code]".

This practice is not just non-standard, even if the [native code] were
allowed it is fallible on two counts that have been discussed.
</aside>

Garrett
 
G

Garrett Smith

kangax said:
Garrett said:
Thomas 'PointedEars' Lahn wrote: [...]
You are mistaken because alert() is a host method (of Window objects,
and
should therefore be called window.alert()). It may display anything
there.

The alert method converts its argument to a string value.

It's surprising that neither MDC, nor MSDN nor HTML5 draft mention
anything about `alert` performing such conversion.

MDC is not perfect.

MSDN is a crapshoot. Some of the documentation is good. However, a lot
it is pretty poor.

HTML5 - I'll post that on the list.
Yes. Some mobile clients have very diverse function representations. I
actually had similar concerns about function decompilation and wrote
about a more reliable way to detect built-in host methods [1].
Unfortunately, my solution is not perfect either, since it relies on
iframe insertion into a document.

Which ones?

You might also want to let PPK know about that.

Your article says you are testing for something in a "non-modified"
context. I assume this means that the context is the newly created
iframe's window object is un-buggered.

Why not just not give the global object an addEventListener property?

Oh, maybe because "somebody might have done that."

In that case that same somebody might not have used standards mode
(doctype) and the document created in the iframe might use standards
mode. Or vice versa (hopefully not that(!)).

You also mention speed. The iframe will also have to be garbage
collected and that will slow things down a bit, too.

There is one other consideration. A pretty serious one, too. In IE,
appending a child mid-parse will result in a lovely "operation aborted"
error[1][2]. This makes the page stop rendering and basically kills your
webapp. So: If your blog is "perfection kills", then I guess you could
call this strategy of appending a node to body while it is being parsed
"perfection".

j/k

:)

So this:-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Detecting built-in host methods</title>
</head>
<body>

<div>
<script type="text/javascript">

var isNativeWindowAddEventListenerPresent = (function(global){
// feature test following methods as needed
var el = document.createElement('iframe');
var root = document.body || document.documentElement;
root.appendChild(el);
var frame = global.frames[global.frames.length-1];
var result = (typeof frame.addEventListener != "undefined");
//root.removeChild(el);
el = null;
return result;
})(this);

</script></div>

</body>
</html>


would result in "operation aborted" error in IE.

The example, as it is written on your blog, gets away with it when the
root.removeChild line is uncommented (as it appears there). It also
works when you don't put the script in a div (which I purposely added to
trigger the error in IE). There should not be a good reason to have that
div anyway. The problem is avoidable, in most cases.

When adding test nodes to body while it is possibly being parsed, I like
use insertBefore(body.firstChild, testEl) instead of appendChild. I have
not had a problem with that yet. I think D Mark and I discussed this
technique about a year ago in "Find Element Position" thread (though I
may be mistaken; we did exchange a good amount of email during that time).

Garrett

[1]http://support.microsoft.com/kb/927917
[2]http://blogs.msdn.com/ie/archive/2008/04/23/what-happened-to-operation-aborted.aspx
 

Ask a Question

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

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

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top