Function name and input name property

I

Ivan S

Hi all.


There is an Javascript error (xxxx is not a function) if there exists
a function name same as input's name (or id) property.


Here is source code sample:

<html>
<head>
<title>Test</title>
<script type="text/javascript">
function test() {
alert("Test");
}
</script>
</head>
<body>
<form>
<input type="button" name="test" onclick="test();" value="Test" />
</form>
</body>
</html>


When input button is clicked, and error message is shown saying "test
function is not defined".


If I change function name, or name property of the input element,
everything works fine.

So, I guess there is a name collision between function name and
input's element name. I don't know why is this happening, can someone
explain it to me? :)



Tnx
 
D

Dmitry A. Soshnikov

[...]
So, I guess there is a name collision between function name and
input's element name. I don't know why is this happening, can someone
explain it to me? :)

[...]

That's 'cause of <form> wrapper for <input>. The code of |onclick|
attribute trabsforms to function object which is created in context,
containing in current scope chain variable object of the <form>. Put |
debugger;| statement into the code and see the scope chain (e.g. in
Firebug or Venkman):

<input ... onclick="alert(test === this); debugger;" />

Scope chain (5 variable objects):

0. Call event=Event click
1. input Test
2. form (with |test| element; that's your "issue")
3. Document
4. Window (with |test| function)

So, identifier resolution in |onclick| evaluated code find the name |
test| in point (3), which contains |test| as form element. If to
remove <form> tag (and form variable object) this code will work as
you want (which means |test| will be found in Window variable object).

/ds
 
B

Bart Van der Donck

Ivan said:
There is an Javascript error (xxxx is not a function) if there exists
a function name same as input's name (or id) property.

Here is source code sample:

<html>
<head>
        <title>Test</title>
        <script type="text/javascript">
                function test() {
                        alert("Test");
                }
        </script>
</head>
<body>
        <form>
                <input type="button" name="test" onclick="test();" value="Test" />
        </form>
</body>
</html>

When input button is clicked, and error message is shown saying "test
function is not defined".

If I change function name, or name property of the input element,
everything works fine.

So, I guess there is a name collision between function name and
input's element name. I don't know why is this happening, can someone
explain it to me? :)

You could use 'onClick="window.test();"' to call the function by its
fully qualified name. But it's never wise to use potentially
conflicting names. Apart from your problem, they may also create
confusion in regard to host/native objects that are already present
(such as here the 'test()'-method in js regular expressions).

Hope this helps,
 
D

Dmitry A. Soshnikov

[...]
0. Call event=Event click
1. input Test
2. form (with |test| element; that's your "issue")
3. Document
4. Window (with |test| function)

So, identifier resolution in |onclick| evaluated code find the name |
test| in point (3)
[...]

Sorry, typo, find in point (2), step (3).
 
T

Thomas 'PointedEars' Lahn

Bart said:
You could use 'onClick="window.test();"' to call the function by its
fully qualified name.

But he should use a reference to the ECMAScript Global Object instead, like

var _global = this;

in the global execution context.
But it's never wise to use potentially conflicting names.
ACK

Apart from your problem, they may also create
confusion in regard to host/native objects that are already present
(such as here the 'test()'-method in js regular expressions).

And it will probably prevent it from being part of a unit test with JSUnit
and perhaps other tools.


PointedEars
 
I

Ivan S

That's 'cause of <form> wrapper for <input>. The code of |onclick|
attribute trabsforms to function object which is created in context,
containing in current scope chain variable object of the <form>. Put |
debugger;| statement into the code and see the scope chain (e.g. in
Firebug or Venkman):

<input ... onclick="alert(test === this); debugger;" />

Scope chain (5 variable objects):

0. Call event=Event click
1. input Test
2. form (with |test| element; that's your "issue")
3. Document
4. Window (with |test| function)

So, identifier resolution in |onclick| evaluated code find the name |
test| in point (3), which contains |test| as form element. If to
remove <form> tag (and form variable object) this code will work as
you want (which means |test| will be found in Window variable object).

/ds

Thanks, this clears things up. :)




Ivan
 

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
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top