473,721 Members | 2,234 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Function declaration inside other function

Best explanation of my question will be an example, look below at this
simple function:

function SetEventHandler (element)
{
// some operations on element

element.onclick =
function(event)
{
// make something
}

}

Everything works fine, but I'm not sure about one thing - will the
onclick event handler be created in memory every time I call function
SetEventHandler , or browser will create only one instance and use it
for every element ? I can of course make that event handler as global
function and assign only reference to onclick event, but I'm just
wondering if there is any diffrence between these two methods.

Thanks for help

Dec 7 '06 #1
28 4325
Larax wrote:
Best explanation of my question will be an example, look below
at this simple function:

function SetEventHandler (element)
{
// some operations on element

element.onclick =
function(event)
{
// make something
}

}

Everything works fine, but I'm not sure about one thing - will the
onclick event handler be created in memory every time I call function
SetEventHandler ,
That is very likely. Javascript is allowed to "join" function objects
if it can know that doing so will make no difference (which would be
the case here as the inner function does not make use of any of the
formal parameters or local variables of the function that contains it).
In practice web browser javascript engines don't seem to ever do this
and instead always create a new and unique function object with each
evaluation of a function expression. Probably the overheads in
determining that "joining" the successive function objects would be
safe too great).
or browser will create only one instance and use it
for every element ?
That would be allowed to here, but there is no evidence of any browsers
doing so.
I can of course make that event handler as global
function and assign only reference to onclick event, but I'm just
wondering if there is any diffrence between these two methods.
The assigning of the inner function forms a closure. If there is no
reason for forming a closure, the issues that may follow (IE's memory
leak issue) and the creation of the multiple function objects make
using the inner function undesirable. See:-

<URL: http://jibbering.com/faq/faq_notes/closures.html >

Richard.

Dec 7 '06 #2
Larax wrote:
function SetEventHandler (element) {
element.onclick = function(event) {
// make something
}
}
Everything works fine, but I'm not sure about one thing - will the
onclick event handler be created in memory every time I call function
SetEventHandler
Yes.

But the previous function will be garbage collected since no reference still
exists to it.

Be careful - the example above creates a memory leak in IE.

Why? Because the element has a reference to the function, and the function
(through its scope chain) has a reference to the element. This circular
reference cannot be detected by IE and it causes a memory leak. Read up on
it and use the Drip tool to detect memory leaks like this.

If you create a global function and merely assign it to the onclick, the
memory leak will not occur.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Dec 7 '06 #3
Thanks for your explanations, I could have ran into serious problems
with the IE memory leak as I'm assigning quite a lot of event handlers
that way.

Larax

Dec 7 '06 #4
VK
Matt Kruse wrote:
Larax wrote:
function SetEventHandler (element) {
element.onclick = function(event) {
// make something
}
}
Everything works fine, but I'm not sure about one thing - will the
onclick event handler be created in memory every time I call function
SetEventHandler
Yes.
Yes. More exactly (to correct OP's wording) on each SetEventHandler
call a new anonymous function will be created, allocated in the memory
and a reference to this anonymous function will be assigned to the
onclick event handler of the DOM [element].
But the previous function will be garbage collected since no reference still
exists to it.
Only if [element] argument points to the same DOM element on each call.
In this case indeed we are overriding onclick handler thus de-reference
the previous anonymous function. If that function was not referenced
anywhere else outside of the function scope (by say obj2.onclick ==
obj1.onclick somewhere) : then the previous anonymous function becomes
GC-available. It will be eventually garbage collected in the period of
time from one system tick to 60sec depending on the system load (60ms -
60000ms for Windows platforms).
Be careful - the example above creates a memory leak in IE.
No, it does not. You must be thinking of the nested functions such as:

function SetEventHandler (element) {
element.onclick = clickListener;

function clickListener(e vent) {
// make something
}
}

which indeed forms a rather nasty closure on each call so it leaks: on
any platform for any browser. This syntax still has its useful
application for particular circumstances - but it should avoided as
hell anywhere else. Alas "inner classes" in Cx and especially in Java
are the sign of a "cool programming style". Because of it – I guess-
a number of Cx/Java programmers jumped on nested functions (for the
lack of classes) to "remain cool even in primitive conditions" :-).
This is more of sociocultural than programming phenomenon: to be
investigated and punished by the project managers 

In case of OP there is nothing of it though, so he's really "cool" :-)

Besides of the known blogs of Eric Lippert it can be also an
interesting additional reading:
<http://msdn.microsoft. com/library/default.asp?url =/library/en-us/ietechcol/dnwebgen/ie_leak_pattern s.asp>
If you create a global function and merely assign it to the onclick, the
memory leak will not occur.
1) That is the oldest well proven way: but it raises the question of
namespace conflicts. So if this way is followed, some additional
notation is needed for functions. The oldest and the simplest one is
the Macromedia notation: two caps producer id - underscore - name:

function LX_clickListene r() {
// make something
}

function LX_SetEventHand ler(element) {
element.onclick = LX_clickListene r;
}

As it's know (or not known so now you know) the opposition of "cool"
and "lame" ("no cool") and overall questions of the current fashion do
play a very important role in the programming. Sometimes they are even
prevailing over purely technical considerations. I may try to explain
it by the specifics of the "programmin g society" with traditionally
high amount of whom either just stopped to be teenager or remained a
bit of teenager no matter what is her real age. This floody preface was
just to say that this programming style (with stay-alone functions)
considered being out of fashion. By the performance it's the most
effective one, but... no cool :-) in case if you decide to show it to
someone. Another problem is that since 1995 a great amount of libraries
has been written and it is not a wander to see a modern page loading
3-5-more modules from different producers. It means that the old two
caps prefix may be too short to exclude with enough of insurance
namespace collisions. That is *not* a crucial default of any kind: just
another aspect to pay attention to.
2) The next way to use static methods is of course the native
JavaScript inheritance mechanics. By adding some method into prototype
you will get this method presented in each object instance (over the
instance prototype chain).

<html>
<head>
<title>Untitl ed Document</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type=”text/javascript”>

function SetEventHandler (element) {
this.element = element;
element.onclick = this.clickListe ner;
}

SetEventHandler .prototype.clic kListener = function(){
window.alert(th is.id);
}

function init() {
var JSxDOM = new SetEventHandler (document.getEl ementById('prob e'));
}

window.onload = init;
</script>
</head>

<body>
<p id="probe">Clic k me</p>
</body>
</head>

There are a few drawbacks of this in your particular situation.
a) prototype applies to the object instances produced by the
constructor, not to the constructor itself. It means that in order to
activate the prototype chain you have to create new object instance
over [new] (unless you are hacking JavaScript instead of *using* it).
That is not always necessary by the program logic - say I see it as not
really necessary in your case (though I may be wrong).
b) DOM interface and JavaScript object are all separate entities
(despite of what Gecko thinks about it :-) That means that within the
conventional programming model (bindings/behaviors aside) you have to
deal then with combos (wrappers) like JSxDOM in the sample above which
is a script object but having a reference on DOM Element. Often it is
not necessary by the program logic plus it requires extra attention
with proper reference removal: so do not create a circular reference
where JS object refers to DOM element and DOM element refers to JS
object.
Say in the sample above we can remove this.element = element; from the
constructor as we do not plan to use it. But it makes the situation
even more bad: i) we are creating an object just to "drop" it right
away which is a bad programming practice; ii) after we are leaving
init() function, JSxDOM - as being local variable - will be garbage
removed but the object it refers to will *not*: it is still referenced
in DOM Element over its clickListener method so it will not garbage
available until DOM Element onclick handler is overridden. That is not
a crucial problem, but easy to forget about.
3) Static methods over function augmentation. What is what I'm using
the most often: but *please* don't take it as "all time best". OK, I
think it is :-) but I'd like to see more critics on it.

<html>
<head>
<title>Untitl ed Document</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script>

function SetEventHandler (element) {
element.onclick = SetEventHandler .clickListener;
}

SetEventHandler .clickListener = function(){
window.alert(th is.id);
}

function init() {
SetEventHandler (document.getEl ementById('prob e'));
}

window.onload = init;
</script>
</head>
<body>
<p id="probe">Clic k me</p>
</body>
</html>

Dec 7 '06 #5
VK wrote:
Matt Kruse wrote:
>Larax wrote:
>>function SetEventHandler (element) {
element.onclick = function(event) {
// make something
}
}
<snip>
>Be careful - the example above creates a memory leak in IE.

No, it does not.
Yes it does. The [[Scope]] property of the function object resulting
from the evaluation of the function expression refers to a scope chain
that includes the Activation/Variable object of the function execution
context it was created within. That Activation/Variable object has an -
element - property that is the result of the declared formal parameter
and the value of that property refers to the DOM Element passed as an
argument. The DOM element is assigned a reference to the function object
and the result is a circular chain of references that goes; DOM Element
(with - onclick - property) -function object (with - [[Scope]] -
property) -scope chain -Activation/Variable object (with - element -
property) -DOM Element.
You must be thinking of the nested functions such as:

function SetEventHandler (element) {
element.onclick = clickListener;

function clickListener(e vent) {
// make something
}
}
Are you thinking that there is a significant difference between the two
when it comes to the IE memory leak issue?
which indeed forms a rather nasty closure
It is a rather ordinary closure.
on each call so it leaks: on
any platform for any browser.
No, it leaks on IE, not all browsers share IE's difficulty in seeing
circular chains of reference as insignificant when they are isolated
from the rest of the system.
This syntax still has its useful application for particular
circumstances - but it should avoided as hell anywhere else.
<snip>

Your advice is worthless if you cannot tell when and why a closure is
being produced and when it is not. So no change there then.

Richard.
Dec 7 '06 #6

Larax wrote:
Thanks for your explanations, I could have ran into serious problems
with the IE memory leak as I'm assigning quite a lot of event handlers
that way.
You can mitigate the memory leak issues by storing references to the
elements that you've attached event handlers to, then removing them
when the unload event occurs. More work certainly, but may be a
cleaner result overall.

The memory leak really only becomes an issue where lots of pages invoke
it and a user opens many such pages without closing IE completely.
Design your application to minimize or nullify its effects by all
means, but don't be too frightened of it.

You might like to look at Richard Cornford's finalizer:

<URL: http://www.litotes.demon.co.uk/examp...finalizer.html >

Dec 8 '06 #7
VK wrote:
Matt Kruse wrote:
>Be careful - the example above creates a memory leak in IE.
No, it does not.
And you question why people think your posts are dangerous to those who wish
to learn?

It will leak.
It's a classic example of the leak scenario.
In fact, one of the very _simplest_ examples of the leak scenario.

"Better to keep your mouth closed and be thought a fool than to open it and
remove all doubt"

Too late.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Dec 8 '06 #8
VK
Matt Kruse wrote:
And you question why people think your posts are dangerous to those who wish
to learn?
A *single* Usenet post of any author is always a dangerous source to
learn anything: unless someone is playing God and others accept this
role. Comments and corrections ("shared knowledge") give the Usenet
it's power.
It will leak.
It's a classic example of the leak scenario.
In fact, one of the very _simplest_ examples of the leak scenario.
Yep, my mistake. I missed that the named function arguments will
participate in closure as well. Funny anough it is mentioned in the
very MSDN article I have linked:
<http://msdn.microsoft. com/library/default.asp?url =/library/en-us/IETechCol/dnwebgen/ie_leak_pattern s.asp>
but somehow I overlooked it.
As a weak excuse (because any of my excuses is weak, is it? :-) I can
say that in-house we are using only only i) 100% guaranteed
non-closures over function augmentation or ii) 100% guaranteed closures
(when needed) so skipping on any even a bit doubtful cases. This way
"closure or not" studies were not conducted for all possible cases.

"Don't use closures unless you really need closure semantics."
(Eric Lippert)

But as this question touched anyway, I'm wandering now about the
situation w/o named arguments:

<html>
<head>
<title>Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

function SetEventHandler () {
if (typeof arguments[0] == 'object') {
arguments[0].onclick = function() {
window.alert(th is.tagName);
};
}
}

function init() {
SetEventHandler (document.getEl ementsByTagName ('p')[0]);
}

window.onload = init;
</script>
</head>
<body>
<h1>Demo</h1>
<p>Click me</p>
</body>
</html>
Does it mean that P sent as anonymous argument is still retained
somewhere in Activation/whatchamacall so forming a circular reference?
"Better to keep your mouth closed and be thought a fool than to open it and
remove all doubt"
Yawn.

I "open my mouth" not to be the smartest one on the block but to say
what I think on the question.

Sometimes (very often as you state) it allows to *others* to show up as
the smartest one around: so I see no reason to complain :-)

Sometimes it allows to break age old myths like "prototypes are used
for defaulting instance variables" (anonymous quote).

Yawn... I'm back to sleep now...

Dec 8 '06 #9
VK wrote:
Matt Kruse wrote:
>And you question why people think your posts are dangerous to those
who wish to learn?

A *single* Usenet post of any author is always a dangerous source to
learn anything: unless someone is playing God and others accept this
role.
Everyone gets to judge for themselves how worth listening to any
individual is.
Comments and corrections ("shared knowledge") give the Usenet
it's power.
Your tendency to disregard corrections and explanations tends to act
against any "power" of Usenet, as it wastes considerable time in
requiring your being re-corrected in order that the victims of your
deranged ramblings do not suffer from taking you seriously.
It will leak.
It's a classic example of the leak scenario.
In fact, one of the very _simplest_ examples of the leak scenario.

Yep, my mistake. I missed that the named function arguments will
participate in closure as well.
How many times has variable instantiation been explained to you now? I
have done so at least twice and I know others have as well.
Funny anough it is mentioned in the
very MSDN article I have linked:
<http://msdn.microsoft. com/library/default.asp?url =/library/en-us/IETechCol/dnwebgen/ie_leak_pattern s.asp>
but somehow I overlooked it.
Even if you had read it you probably would not have understood.
As a weak excuse (because any of my excuses is weak, is it? :-) I can
say that in-house we are using only only i) 100% guaranteed
non-closures over function augmentation or ii) 100% guaranteed closures
(when needed) so skipping on any even a bit doubtful cases.
<snip>

Nonsense. In order to control when to use closures and when not to it
is necessary to understand how and when they are created. You have
repeatedly demonstrated, here and in previous code you have posted to
the group, that you have little comprehension of what is going on in
executing javascript, and certainly don't understand closures.

However, as you could not be employed in any organisation that also
employed real programmers (as your incompetence would then be pointed
out to however was in charge) talking of "in-house" doesn't mean much,
and certainly is not something that will be taken as guidance by the
rational.
But as this question touched anyway, I'm wandering now about the
situation w/o named arguments:
There is no need to wonder, understand javascript and you will know.

<snip>
function SetEventHandler () {
if (typeof arguments[0] == 'object') {
arguments[0].onclick = function() {
window.alert(th is.tagName);
};
}
}
<snip>
Does it mean that P sent as anonymous argument is still retained
somewhere in Activation/whatchamacall so forming a circular
reference?
Yes of course it is; - arguments - is a property of the
Activation/Variable object and the object referred to by - arguments -
has a - 0 - property that is a reference to the DOM Element.
>"Better to keep your mouth closed and be thought a fool than to open
it and remove all doubt"

Yawn.

I "open my mouth" not to be the smartest one on the block but to say
what I think on the question.
But what you think is not informed by any understanding of the subject.
Indeed it is mostly a deranged fantasy with little connection to the
real world.
Sometimes (very often as you state) it allows to *others* to show up as
the smartest one around: so I see no reason to complain :-)
There is no need for a "smartest one around" competition in correcting
you, you know so little about javascript that even relative novices
understand more than you. You do appear to be yourself competing in a
'most incapable of learning' competition, as it takes a considerable
effort on the part of many individuals to get you to take any tiny step
towards a better understanding of javascript.
Sometimes it allows to break age old myths like "prototypes are used
for defaulting instance variables" (anonymous quote).
<snip>

Why anonymous? That is a true statement. That you think of it as a
"myth" is a product of your failure to comprehend javascript, that you
think you may have broken that "myth" is a product of your
self-delusion. You will learn more, and more quickly, if you do not
take the position that you are right and everyone else is wrong. The
result of that attitude has already made you look ridiculous.

You open your mouth and again leave everyone in no doubt that you are a
fool.

Richard.

Dec 8 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
4943
by: Dave Theese | last post by:
Consider the following declaration *inside of a function*: int j(int); My compiler (VC++ 7.1) accepts this. typeid returns a type of int __cdecl(int). Local functions are not legal in C++. Is this an error or... Is there some reason it would be legal to declare (but not define) a
2
3984
by: Ruben Campos | last post by:
I have a problem with a template function that is declared as a friend of a template class. I'll first show the exact problem with source code: // MyClass.hpp template <typename T> class MyClass { // ... friend void MyFriendFunction (MyClass <T> * const ptrMyClass); // ...
2
8831
by: Thomas Matthews | last post by:
Hi, I'm getting linking errors when I declare a variable in the global scope, but not inside a function. The declarations are the same (only the names have been changed...). class Book { public: Book()
4
15849
by: Brett | last post by:
I'm trying to use the F1 function inside of F2 function below. I keep getting the error posted below the code. If I remove the Shared declaration from F2, it works fine. What exactly does the error mean? Public Class myClass Function F1(ByVal url As String) As Struct1 -- do something -- End Function
3
3063
by: hugheslin | last post by:
Hi, Please consider the following classes: ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class Shape { ...... ...... public:
11
10989
by: rherring | last post by:
Hello, I have some C++ code that builds against 2 headers files that contain the same function name declaration (gethostname). The header files are not directly included. They are included via other header files. How can I resovle this error? The error (GCC 3.3.2 on Solaris 9): /usr/include/unistd.h:278: error: declaration of C function `int
20
2370
by: Christian Christmann | last post by:
Hi, in a benchmark I've found an uncommon use of a function. This is the simplified form: 1 int foo( int f ) 2 { 3 return f; 4 } 5
4
2717
by: Ray | last post by:
Hello, I think I've had JavaScript variable scope figured out, can you please see if I've got it correctly? * Variables can be local or global * When a variable is declared outside any function, it is global regardless of whether it's declared with or without "var" * When it is declared inside a function, if declared with "var", it's local, if not, it's global
4
2515
by: Paulo Matos | last post by:
Hi all, I'm trying to work out a parser for function declarations but it turns out that it is harder than I initially thought. I'm looking at 3rd Ed of Stroustrup, page 808. I'm trying to parse something like: int foo(int, int); const double *xpto(mytype *, mytype &) const; But I'm not being able to find my way around the grammar.
0
8730
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9367
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9215
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8007
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6669
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4484
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4753
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3189
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2576
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.