By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,609 Members | 3,812 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,609 IT Pros & Developers. It's quick & easy.

id names are global variables?

P: n/a
When I do this:

<input id="someName" type="text">

<script type="text/javascript">
alert(someName.nodeName);
</script>

Both IE6 and Firefox alert("INPUT"). Why isn't "someName" undefined?

Why am I not required to do something like this:

getElementById("someName").nodeName;
Oct 2 '08 #1
Share this Question
Share on Google+
18 Replies


P: n/a
Bruce wrote:
<input id="someName" type="text">

<script type="text/javascript">
alert(someName.nodeName);
</script>

Both IE6 and Firefox alert("INPUT"). Why isn't "someName" undefined?

Why am I not required to do something like this:

getElementById("someName").nodeName;
Backwards compatibility and maybe compatibility to one another. In Firefox
it would work only because you are triggering Quirks Mode by omitting the
DOCTYPE declaration or providing an incomplete one.

<http://validator.w3.org/>
PointedEars
--
Prototype.js was written by people who don't know javascript for people
who don't know javascript. People who don't know javascript are not
the best source of advice on designing systems that use javascript.
-- Richard Cornford, cljs, <f8*******************@news.demon.co.uk>
Oct 2 '08 #2

P: n/a
On Oct 2, 2:29*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>
Backwards compatibility and maybe compatibility to one another. *In Firefox
it would work only because you are triggering Quirks Mode by omitting the
DOCTYPE declaration or providing an incomplete one.
Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
Oct 2 '08 #3

P: n/a
On Thu, 02 Oct 2008 12:45:19 -0700, Bruce wrote:
Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
IE6, or rather, all versions of IE to date, are a pain. Some browsers
even go as far as duplicating IE bugs^w features.

My recommendation: Don't pollute the global name space.

All class/instance variables should be declared locally. If, for some
reason, you need two functions to share a group of variables, wrap the
two functions up together.

If you MUST use globals, use just one. Make an object and set properties.

<html>
<head>
<title>Test</title>
</head>
<body>

<script type="text/javascript">

var jjsGlobal = {}; // One variable to rule them all

function w(s)
{
document.write(s + "<br>");
}

(function() {
var onlySeenHere = 0;;

function test1() {
onlySeenHere++;;
}

function test2() {
onlySeenHere++;;
}

test1();
test2();
w("OnlySeenHere = " + onlySeenHere);

jjsGlobal.test = "Test is set.";

})();
w("And our global == " + jjsGlobal.test);
</script>

</body>
</html>
Oct 2 '08 #4

P: n/a
Bruce wrote:
Thomas 'PointedEars' Lahn wrote:
>Backwards compatibility and maybe compatibility to one another. In Firefox
it would work only because you are triggering Quirks Mode by omitting the
DOCTYPE declaration or providing an incomplete one.

Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
Which problem?

BTW, there are no classes in these languages:
<http://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages>
<http://javascript.crockford.com/inheritance.html>
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
Oct 2 '08 #5

P: n/a
On Oct 2, 3:03*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Bruce wrote:
Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.

Which problem?
The problem with ids also being global variables.
Oct 2 '08 #6

P: n/a
On Oct 2, 3:00*pm, Jeremy J Starcher <r3...@yahoo.comwrote:
>
My recommendation: *Don't pollute the global name space.
Of course but I haven't found a better way yet. I'm writing a simple
spreadsheet like calculator.

I want to do the following:

<input id="a1" type="input"+
<input id="b1" type="input"=
<input id="c1" type="input" readonly>

Then pass the following to a "class"

"c1 = a1 + b1"

I want to use eval() to do the math. I want to keep 2 copies of the
variables. The displayed value is kept in the input form field, and a
higher precision value is kept in a variable matching the name of the
input form field.

I want to check to see if the variable has been defined. If not I
create it in the global namespace and set it to a default value. With
IE6 the variables are already defined as objects because of the input
form ids so it doesn't work.

In this simple example, if I do this:

var a1;
var b1;

It works, but for larger spreadsheets, I don't want to have to do
that. I want to do it automatically. For every input form id I find, I
want to create a global variable so that the simple math string will
work in an eval()
Oct 2 '08 #7

P: n/a
Bruce meinte:
On Oct 2, 3:03 pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>Bruce wrote:
>>Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
Which problem?

The problem with ids also being global variables.
Since you hardly ever need global variables, there is no spoon^Wproblem.

Gregor
--
http://photo.gregorkofler.at ::: Landschafts- und Reisefotografie
http://web.gregorkofler.com ::: meine JS-Spielwiese
http://www.image2d.com ::: Bildagentur fr den alpinen Raum
Oct 2 '08 #8

P: n/a
On Thu, 02 Oct 2008 13:45:54 -0700, Bruce wrote:
On Oct 2, 3:00*pm, Jeremy J Starcher <r3...@yahoo.comwrote:
>>
My recommendation: *Don't pollute the global name space.

Of course but I haven't found a better way yet. I'm writing a simple
spreadsheet like calculator.

I want to do the following:

<input id="a1" type="input"+
<input id="b1" type="input"=
<input id="c1" type="input" readonly>

Then pass the following to a "class"

"c1 = a1 + b1"

I want to use eval() to do the math. I want to keep 2 copies of the
variables. The displayed value is kept in the input form field, and a
higher precision value is kept in a variable matching the name of the
input form field.

I want to check to see if the variable has been defined. If not I create
it in the global namespace and set it to a default value. With IE6 the
variables are already defined as objects because of the input form ids
so it doesn't work.

In this simple example, if I do this:

var a1;
var b1;

It works, but for larger spreadsheets, I don't want to have to do that.
I want to do it automatically. For every input form id I find, I want to
create a global variable so that the simple math string will work in an
eval()
No global variables! Not here! In other posts I demonstrated how to
avoid using global variables.

You don't want to create a new variable for every field. You _really_
don't.

Without knowing more about how you are planning making this, I can think
of several approaches that would do you MUCH better.

Approach 1:
Simple, easy to understand but not elegant.

2D arrays, [column][row]
A-Z would become 0-26, so a10 would become displayedValue[0][10],
calculatedValue[0][10]
Approach 2:
Objects

Objects are the perfect tool to store data like this. You would write
code like

var spreadSheet = {}; // Create a new object.
spreadSheet.a10 = {}; // Create a new cell.

var cId = "b10";
spreadSheet[cId] = {}; // Create a new cell

spreadSheet.a10.displayedValue = 10;
spreadSheet.a10.calcValue = 9.9999999999999999999999;
Your approach hints at a background programming in BASIC or some other
earlier language. Languages have moved beyound that.

Before you code any more, do some heavy reading on Javascript, Arrays and
Objects (incorrectly called associative arrays).


Oct 2 '08 #9

P: n/a
Your approach hints at a background programming in BASIC or some other
earlier language. *Languages have moved beyound that.

Before you code any more, do some heavy reading on Javascript, Arrays and
Objects (incorrectly called associative arrays).- Hide quoted text -
I'm not doing it this way because I'm clueless and I like global
variables, nor am I new to Javascript or to Structured Programming or
Object Oriented programming.

I'm trying to keep my equations as simple as "c1 = a1 + b1" just like
in an Excel spreadsheet. The simplest way that I've thought of so far
is to let a1, b1, c1 be global variables so that eval("c1 = a1 + b1")
will work.

I don't want my equations to look like this:

eval("myObj.c1 = myObj.a1 = myObj.b1");

Or

eval("myArray[0][2] = myArray[0][0] = myArray[0][1]");

If I can find a way, short of writing my own equation parser, to do
this without global variables, I'm all for it.
Oct 2 '08 #10

P: n/a
Bruce wrote:
Thomas 'PointedEars' Lahn wrote:
>Bruce wrote:
>>Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
Which problem?

The problem with ids also being global variables.
Why is that a problem?
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
Oct 2 '08 #11

P: n/a
Gregor Kofler wrote:
Bruce meinte:
>Thomas 'PointedEars' Lahn wrote:
>>Bruce wrote:
Yes, you're right. I forgot the DOCTYPE. That fixes the problem for
Firefox but what a nuisance that the problem persists in IE6.
Which problem?
The problem with ids also being global variables.

Since you hardly ever need global variables, there is no spoon^Wproblem.
YMMD :)
\\// PointedEars, who's got a Matrix to fix
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Oct 2 '08 #12

P: n/a
On Oct 2, 4:25*pm, Bruce <batman4...@yahoo.cawrote:
I'm trying to keep my equations as simple as "c1 = a1 + b1" just like
in an Excel spreadsheet.
If I can find a way, short of writing my own equation parser, to do
this without global variables, I'm all for it.
Thanks to a suggestion from Jeremy J Starcher in another thread, I
found my solution.

Instead of global variables, I create variables within my "class" like
this:

this["a1"] = 1;
this["b1"] = 2;

then I can do this:

with(this) {
c1 = eval("a1 + b1");
}

Problem solved. No global variables and I get to keep my simple
equations.
Oct 3 '08 #13

P: n/a
Bruce wrote:
On Oct 2, 4:25 pm, Bruce <batman4...@yahoo.cawrote:
>I'm trying to keep my equations as simple as "c1 = a1 + b1" just like
in an Excel spreadsheet.
Excel is certainly not a programming reference.
>If I can find a way, short of writing my own equation parser, to do
this without global variables, I'm all for it.

Thanks to a suggestion from Jeremy J Starcher in another thread, I
found my solution.

Instead of global variables, I create variables within my "class" like
this:

this["a1"] = 1;
this["b1"] = 2;
this.a1 = 1;
this.b1 = 2;

is equivalent since the property names are identifiers.
then I can do this:

with(this) {
c1 = eval("a1 + b1");
You rarely ever need eval(), and you certainly don't need it here:

c1 = a1 + b1;

or

c1 = this.a1 + this.b1;
}

Problem solved. No global variables and I get to keep my simple
equations.
No, you cannot if the data comes from form controls.

However, you could use a form (here: referred to by the `form' property of
the calling object) directly, whereas `a1' or `b1' are IDs or names of form
controls (with the latter being better supported):

with (this.form.elements)
{
c1 = parseFloat(a1.value) + parseFloat(b1.value);
}

or without the `with' statement:

var es = this.form.elements;
var a1 = es["a1"].value;
var b1 = es["b1"].value;
var c1 = parseFloat(a1) + parseFloat(b1);
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Oct 3 '08 #14

P: n/a
On Oct 2, 8:22*pm, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
Bruce wrote:
On Oct 2, 4:25 pm, Bruce <batman4...@yahoo.cawrote:
I'm trying to keep my equations as simple as "c1 = a1 + b1" just like
in an Excel spreadsheet.

Excel is certainly not a programming reference.
I didn't make a programming reference to Exel. I made a reference to
the way equations are entered into Excel.

I'm writing a general purpose "class" where I can configure it with
strings of equations using form id names as variable names that will
update other form fields as the input data changes. I want my
"spreadsheet" calculation to be as unobtrusive as possible so that I
create a form with id names for variable names and my "class"
automates the rest (adds "onchange" events, initializes form field
values ...).
>
this["a1"] = 1;
this["b1"] = 2;

* this.a1 = 1;
* this.b1 = 2;
I have to do

this["a1"] = 1

because I pass variable names to my "class" as string names. I want to
configure the class with equations in the form of strings. I will pass
something like "c1 = a1 + b1" as a string to my class.

So I'm actually doing something like this (as a trivial example):

setDefaults : function(variableNames,defaultValue) {
for (var i = 0; i < variableNames.length; i++) {
this[variableNames[i]] = defaultValue;
}
}
You rarely ever need eval(), and you certainly don't need it here:

* c1 = a1 + b1;

or

* c1 = this.a1 + this.b1;
Can't. I'm passing variable names as strings. I'm passing equations as
strings. So, yes I need eval() or I need to write my own equation
parser. Eval() already does that for me so I might as well use it.
Problem solved. No global variables and I get to keep my simple
equations.

No, you cannot if the data comes from form controls.
I completely control the equations. Users do not input them so they
won't be able to inject unwanted Javascript.

My application will not look like a spreadsheet. It will look like a
form where users input some data and I perform preconfigured math on
the data and display things like a running total in real time. Since I
want this code to be re-useable on other web sites, I'll configure the
code with an array of equations and variable names as strings and use
eval() to perform the math.

Oct 3 '08 #15

P: n/a
Bruce wrote:
Thomas 'PointedEars' Lahn wrote:
>Bruce wrote:
>>this["a1"] = 1;
this["b1"] = 2;
this.a1 = 1;
this.b1 = 2;

I have to do

this["a1"] = 1

because I pass variable names to my "class" as string names.
In that case you would have to. It would restrict "string names" to unused
property names of the implementation, that you cannot know, though.
>You rarely ever need eval(), and you certainly don't need it here:

c1 = a1 + b1;

or

c1 = this.a1 + this.b1;

Can't. I'm passing variable names as strings. I'm passing equations as
strings.
IOW, you are passing *code* as strings.
So, yes I need eval() or I need to write my own equation parser.
Eval() already does that for me so I might as well use it.
Plain eval() constitutes a security leak. The least you have to do is
removing potentially harmful code from the passed string. And CMIIW,
the halting problem is not yet solved.
>>Problem solved. No global variables and I get to keep my simple
equations.
No, you cannot if the data comes from form controls.

I completely control the equations. Users do not input them so they
won't be able to inject unwanted Javascript. [...]
If users do not input the equations, there is no need to use eval().
PointedEars
--
Anyone who slaps a 'this page is best viewed with Browser X' label on
a Web page appears to be yearning for the bad old days, before the Web,
when you had very little chance of reading a document written on another
computer, another word processor, or another network. -- Tim Berners-Lee
Oct 3 '08 #16

P: n/a
On Oct 3, 7:25*am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
because I pass variable names to my "class" as string names.

In that case you would have to. *It would restrict "string names" to unused
property names of the implementation, that you cannot know, though.
I can know, because I choose the variable names. I choose the id names
in the form fields. I also choose the equations. The only thing chosen
by the user is the data.
Can't. I'm passing variable names as strings. I'm passing equations as
strings.

IOW, you are passing *code* as strings.
Here's something I don't know. Can code be injected if I parseFloat()
on user input? I suspect not but I'm not a determined hacker. The
value of the variables is input by the user. The equations that go
through eval() and the variable names, are coded by me.
If users do not input the equations, there is no need to use eval().
I pass an array of equations in the form of strings to my "class". For
example:

var myMath = [ "c1=a1+b1","d2=(c1+c2)*10" ];
myClass.performMath(myMath);

I could modify the code of my "class" every time I need a new set of
equations for a new web site but I'd rather keep the "class" read only
and just pass it new equations as data.
Oct 3 '08 #17

P: n/a
Bruce wrote:
Thomas 'PointedEars' Lahn wrote:
>>because I pass variable names to my "class" as string names.
In that case you would have to. It would restrict "string names" to
unused property names of the implementation, that you cannot know,
though.

I can know, because I choose the variable names. [...]
OK.
>>Can't. I'm passing variable names as strings. I'm passing equations
as strings.
IOW, you are passing *code* as strings.

Here's something I don't know. Can code be injected if I parseFloat() on
user input? [...]
In theory, yes, as the argument is converted to string which would call the
toString() or valueOf() method of an object that the argument refers to
(ES3F, 15.1.2.3, 9.8, 9.1):

function foo(bar)
{
// alerts 42
var baz = parseFloat(bar);
}

foo({
toString: function() {
window.alert(42);
return "0";
}
});

However, form control values are represented as strings, and type conversion
of a string to string does not call any of the aforementioned methods.
>If users do not input the equations, there is no need to use eval().

I pass an array of equations in the form of strings to my "class". For
example:

var myMath = [ "c1=a1+b1","d2=(c1+c2)*10" ];
myClass.performMath(myMath);

I could modify the code of my "class" every time I need a new set of
equations for a new web site but I'd rather keep the "class" read only
and just pass it new equations as data.
You can pass Function object references instead, and your object
(let's get rid of `"class"') can call it as one of its methods.
Quick hack:

function Earth()
{
this.a2 = 7;
}

Earth.prototype.compute = function(f) {
if (f && typeof f == "function")
{
if (typeof f.call == "function")
{
return f.call(this);
}
else
{
this.tmp = f;
return this.tmp();
}
}
};

var earth1 = new Earth();

// thanks to the Golgafrinchams
earth1.a2 = 9;

// alas, it does not show fourty-two
window.alert(
earth1.compute(
function() {
this.a1 = 6;
return this.a1 * this.a2;
}));

// let's try again ;-)
earth1 = null;
var earth2 = new Earth();
PointedEars
--
Use any version of Microsoft Frontpage to create your site.
(This won't prevent people from viewing your source, but no one
will want to steal it.)
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Oct 5 '08 #18

P: n/a
Bruce wrote:
When I do this:

<input id="someName" type="text">

<script type="text/javascript">
alert(someName.nodeName);
</script>

Both IE6 and Firefox alert("INPUT"). Why isn't "someName" undefined?

Why am I not required to do something like this:

getElementById("someName").nodeName;
There seems to be some sort of object that resolves element IDs in
various browsers.

http://groups.google.com/group/comp....d8ecf1660e1dd1

I have updated the relevant section of the FAQ:
http://jibbering.com/faq/#globalPollution

It used to read:-

| 4.41 Why doesn't the global variable "divId" always refer to the
| element with id="divId"?
|
| Microsoft introduced a shortcut that can be used to reference elements
| which include an ID attribute where the ID becomes a global variable.
| Some browsers reproduce this behaviours but some, most notably
| Gecko-based browsers (Netscape and Mozilla), do not. The best approach
| is the document.getElementById method, which is part of the W3C DOM
| standard and implemented in modern browsers (including IE from version
| 5.0). So an element with id="foo" can be referenced with:-
|
| var el = document.getElementById("foo");

Replaced "global variable" with globally accessible property. Changed
"Gecko-based browsers (Netscape and Mozilla), do not." to "Gecko-based
browsers (Netscape and Mozilla), do so only in "quirks" mode."
Oct 7 '08 #19

This discussion thread is closed

Replies have been disabled for this discussion.