javascript passing by reference problem

G

ged

Hi,

i am a oo (c#) programmer, and have not used javascript for a while and
i cant work out how javascript manages its references. Object
References work for simple stuff, but once i have an object collection
and stanrd using it it starts to fall apart.
Clearly there is something about javascript's usage of passing "By ref"
that i am not getting. i have had a look on the web and found some
examples, but i cant see why my code does not work. Grrrrh. I really
need to know why because i am writng a large app in javascript and
Ajax.

I program in c# mainly and i am applying soem OO principles to my
javascript but i am goign nust with how its works sometimes.

Also on a side not i dont get why i code javaScript this way to make it
work?

var personEntity = new PersonEntity("ged", 35);
document.write(personEntity.Name;

function PersonEntity(name, age)
{
var Name = name;
var Age - age;
}

it has to be instead:
function PersonEntity(name, age)
{
this.Name = name;
this.Age = age;
}


i have a sneaking suspicion that the above example also has something
to do with my misunderstanding of the javascript reference pointers
work.

Code is below as a complete test. You just have to save it and load
into your browser and it will run telling you where it errored. I
really want an answer on this and am trying to make it easy for someone
to tell me why is DOES NOT WOKR .

thansk in advance

Ged


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Reference Test</title>


<script language="JavaScript">

// Constants maps to static UI element ids
var APP_ICON_XPLORER_ID = "XplorerAppIcon";
var APP_ICON_GIMP_ID = "GimpAppIcon";
var APP_PANEL_XPLORER_ID = "XplorerAppPanel";
var APP_PANEL_GIMP_ID = "GimpAppPanel";

var g_appController = new AppController();
var g_appModel = new AppModel();

function AppInit()
{
// create app objects to map Dom Elements to other aspects
var xplorerApp = new AppItem('Xplorer', APP_ICON_XPLORER_ID,
APP_PANEL_XPLORER_ID);
g_appModel.Add(xplorerApp);

var gimpApp = new AppItem('Gimp', APP_ICON_GIMP_ID,
APP_PANEL_GIMP_ID)
g_appModel.Add(gimpApp);


// DO test of item being clicked
g_appController.AppItemLoadCommand(APP_ICON_XPLORER_ID);

}
function AppController()
{
// App Icon clicked
this.AppItemLoadCommand = function(id)
{

// resolve item clicked
var appItem = g_appModel.GetAppItemByIconElementId(id);

document.write("appItem.appIconElementId : " +
appItem.appIconElementId + "<BR />");

// Set Model
g_appModel.SetCurrentItem(appItem);

// Set View
var appView = AppView();
appView.SetFocus(g_appModel.appList, appItem);
}
}// JScript File


function AppModel()
{
this.currentItem = null;
this.appList = new Array();

this.Add = function(appItem)
{
this.appList[this.appList.length] = appItem;
};

this.GetAppItemByIconElementId = function(id)
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].appIconElementId == id)
{
return this.appList[x];
}
return null;
}
}

this.GetAppItemByPanelElementId = function(id)
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].appPanelElementId == id)
{
return this.appList[x];
}
return null;
}
}

this.SetCurrentItem = function(appitem)
{
document.write("Testing object passed by reference now <BR
/>");
// !! This fails to have the object passed in - whats gives
?//
// Gtes appItem is Not defines in javascript console //
document.write("appItem.appIconElementId : " +
appItem.appIconElementId);
appItem.isCurrent = true;
}

this.GetCurrentItem = function()
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].isCurrent == true)
{
return this.appList[x];
}
return null;
}
}
}

function AppItem(name, appIconElementId, appPanelElementId)
{
this.name = name;
this.appIconElementId = appIconElementId;
this.appPanelElementId = appPanelElementId;
this.isCurrent = false;
}

</script>



</head>
<body onLoad="javaScript:AppInit();>

Reference Test



<body>
 
T

Thomas 'PointedEars' Lahn

ged said:
var personEntity = new PersonEntity("ged", 35);
document.write(personEntity.Name;
----------------------------------^
SyntaxError: missing ) after argument list
function PersonEntity(name, age)
{
var Name = name;
var Age - age;
------------------^
SyntaxError: missing ; before statement
}

it has to be instead:
function PersonEntity(name, age)
{
this.Name = name;
this.Age = age;
}

Of course.
i have a sneaking suspicion that the above example also has something
to do with my misunderstanding of the javascript reference pointers
work.

Maybe. Ignoring what could be typos: local variables of a constructor
do not become properties of objects created through it.
Code is below as a complete test. You just have to save it and load
into your browser and it will run telling you where it errored. I
really want an answer on this and am trying to make it easy for someone
to tell me why is DOES NOT WOKR .
[...]

"Does not work" is a useless error description. [psf 4.11]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

Neither does IE support XHTML, nor is your markup Valid XHTML 1.0
Transitional. said:

No, thanks.
<body onLoad="javaScript:AppInit();>

Labels like `javaScript:' do not belong into code in event handler attribute
values. The default scripting language should be declared via `meta'
element within the `head' element for UAs that support it according to the
HTML 4.01 Specification.

Identifiers not referring to functions used as constructors should not start
with an uppercase letter in order to avoid confusion and undesired side
effects.


PointedEars
 
R

Richard Cornford

ged said:
i am a oo (c#) programmer,

Your shift key seems to be intermittent. If you are going to attempt to
engage in written communication (or computer programming for that
matter) it may prove advantageous to have your keyboard serviced or
replaced.
and have not used javascript for a while and i cant work
out how javascript manages its references.

Javascript leaves the mechanism of references to objects up to the
implementers. The only important detail is that when an object property
is assigned the value 'of an object' the resulting value refers to that
object, and when a value that is 'of an object' is passed as an argument
to a function call it is the value that refers to the object that is
passed (the functions formal parameter will refer to the same object
instance).
Object References work for simple stuff, but once i have an
object collection and stanrd using it it starts to fall apart.

Implementations are consistent in the way that they handle object
references (that is, the resulting behaviour is consistent) so that is
likely to follow from some misconception.
Clearly there is something about javascript's usage of
passing "By ref" that i am not getting.

And an explanation if what it is that you are expecting is probably the
best way of getting an explanation of where your expectations do not
corresponds with reality.
i have had a look on the web and found some examples, but
i cant see why my code does not work.

But your code does work, in the sense that it does exactly what you have
programmed it to do. So the question becomes; what is it that you want
it to do? or; what would qualify as working?
Grrrrh. I really need to know why because i am writng a large
app in javascript and Ajax.

AJAX implies javascript.
I program in c# mainly and i am applying soem OO principles
to my javascript but i am goign nust with how its works
sometimes.

Also on a side not i dont get why i code javaScript this way
to make it work?

var personEntity = new PersonEntity("ged", 35);
document.write(personEntity.Name;

function PersonEntity(name, age)
{
var Name = name;
var Age - age;
}

Assuming that the subtraction operation is a typo (or another symptom of
your defective keyboard), this is a futile function as a function's
formal parameters, local variables and inner function declarations
result in the creation of named properties of the 'Activation/Variable'
object that sites at the top of the scope chain form the execution of
the function body. The Activation/Variable object is only accessible
through the scope chain. (See ECMA 262, 3rd edition; Sections 10.1.4 and
10.2)

Any object created with this constructor4 will not have a public 'Name'
property, so the document.write above would output 'undefined'.
it has to be instead:
function PersonEntity(name, age)
{
this.Name = name;
this.Age = age;
}

The - this - keyword refers to the object being constructed when this
function is used as a constructor. You create a 'Name' property of that
object and assign a value to it, so the document.write will wrote out
the value of that property.
i have a sneaking suspicion that the above example also has
something to do with my misunderstanding of the javascript
reference pointers work.

Looks like you need to understand javascript's scopeing, identifier
resolution and the looking up/creation of properties on objects. Try:-

Code is below as a complete test. You just have to save it
and load into your browser and it will run telling you where
it errored. I really want an answer on this and am trying to
make it easy for someone to tell me why is DOES NOT WOKR .

Would it have been so much effort to actually write down what the error
was and indicate which line produced it. The error reported by IE is
"'appItem' is undefined" (line 96, char 9). That line is inside of the -
SetCurrentItem - method of the - AppModel - object. And it happens
because there is no object on the scope chain of that method with a
property named 'appItem'.
thansk in advance

Ged


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

Yikes, an XHTML doctype. You don't want to be scripting XHTML in a
commercial context as the additional effort required to accommodate IE's
lack of support for XHTML considerably exceeds the negligible returns in
using that type of mark-up.
<head>
<title>Reference Test</title>


<script language="JavaScript">

In valid (x)HTML the LANGUAGE attribute of SCRIPT elements is deprecated
and the TYPE attribute is required.

<script type="text/javascript">

function AppController()
{
// App Icon clicked
this.AppItemLoadCommand = function(id)
{

// resolve item clicked
var appItem = g_appModel.GetAppItemByIconElementId(id);

document.write("appItem.appIconElementId : " +


This is a significant problem is you int4end attempting to use XHTML as
no current XHTML DOM implementation supports the document.write method.
That is, if there is any chance of this document ever being interpreted
as anything other than error-filled HTML the code will instantly break
as the document.write calls will fail.
appItem.appIconElementId + "<BR />");

And if this document is intended to be served as 'text/html' and so
interpreted as error-filled HTML, error corrected back to tag-soup HTML,
and an HTML DOM created from the result (so that the document.write
method will work at all) there is little point in document.writie-ing
XHTML style mark-up. Doing so is just irrational.
// Set Model
g_appModel.SetCurrentItem(appItem);

// Set View
var appView = AppView();
appView.SetFocus(g_appModel.appList, appItem);
}
}// JScript File

It is a universally good idea to indent source code (and do so
appropriately when posting code to newsgroups, i.e. with spaces instead
of tabs). Here you have the call to the SetCurrentItem - method that
results in the error. The local variable 'appItem' has its value passed
as the argument to the method call.
function AppModel()
{
this.currentItem = null;
this.appList = new Array();

this.Add = function(appItem)
{
this.appList[this.appList.length] = appItem;
};

This inner function expression will result in the creation of a new
function object and the assignment of a reference to that new function
object to th4e 'Add' property of this object instance. The same process
is repeated for each instantiation of an instance of 'AppModel'. The
function created is not exploiting its status as an inner function and
so there is no need for each instance of 'AppModel' to have a distinct
function object instance as its 'Add' method.
this.GetAppItemByIconElementId = function(id)
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].appIconElementId == id)
{
return this.appList[x];
}
return null;
}
}

The same as above applies to this 'GetAppItemByIconElementId' method.
this.GetAppItemByPanelElementId = function(id)
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].appPanelElementId == id)
{
return this.appList[x];
}
return null;
}
}

The same as above applies to this 'GetAppItemByPanelElementId' method.
this.SetCurrentItem = function(appitem)

Observe that you defective keyboard has bitten you here. If this
method's formal parameter had an uppercase I instead of lower case then
the error "'appItem' is undefined' would not happen as 'appItem' would
then refer to the formal parameter.
{
document.write("Testing object passed by reference now <BR
/>");
// !! This fails to have the object passed in - whats gives
?//
// Gtes appItem is Not defines in javascript console //
document.write("appItem.appIconElementId : " +
appItem.appIconElementId);
^^^^^^^
There is your error. It looks like you intended to refer to the method's
parameter but have actually used an Identifier that does not resolve as
a named property of any object on the method's scope chain.
appItem.isCurrent = true;
}

The same as above applies to this 'SetCurrentItem' method.
this.GetCurrentItem = function()
{
for(var x=0; x < this.appList.length; x++)
{
if(this.appList[x].isCurrent == true)
{
return this.appList[x];
}
return null;
}
}

The same as above applies to this 'GetCurrentItem' method.
<snip>

All of this worthless creation of function object instances with each
creation of an ' AppModel' instance can be avoided by assigning a single
function object instance to named properties of the constructor's
prototype. E.G:-

function AppModel()
{
this.currentItem = null;
this.appList = new Array();
}

AppModel.prototype.Add = function(appItem)
{
...
};
AppModel.prototype.GetAppItemByIconElementId = function(id)
{
...
};
AppModel.prototype.GetAppItemByPanelElementId = function(id)
{
...
};
AppModel.prototype.SetCurrentItem = function(appitem)
{
...
};
AppModel.prototype.GetCurrentItem = function()
{
...
};

Richard.
 
G

ged

hi Pointed Ears,

The question was about handlng variable declarations by reference (i.e.
pointers), but thanks for your pointers( excuse the pun ) about teh
docuemtn not validating agaisnt rhe w3c schema.

anyway it all was a stupid miss-typing on my part of the arguement of
the method signature - Dumb really.
Turns out JavaScript handles ponters very nicely, unlike a lot of
confused assumptions and answers i have on the net.

For anyones reading this - the answer to my question is:
The pointers are handled in the same way most OO languages manage them.
The trick is the correct use of the "this" keyword. Nested functions
are essentially methods and parent functions are classes.
As long as i rememebr this then the use of the "this" keywork is
exactly the same as in c#.

Thansk again and i consider this closed.

Regards

Gerard
 
T

Thomas 'PointedEars' Lahn

ged said:
hi Pointed Ears,

My nickname is spelled "PointedEars", thanks in advance.
The question was about handlng variable declarations by reference (i.e.
pointers), but thanks for your pointers( excuse the pun ) about teh
docuemtn not validating agaisnt rhe w3c schema.

(Your keyboard really /is/ dysfunctional.)

"w3c schema"? You have no clue what you are talking about.
[...]
Turns out JavaScript handles ponters very nicely, unlike a lot of
confused assumptions and answers i have on the net.

For anyones reading this - the answer to my question is:
The pointers are handled in the same way most OO languages manage them.
The trick is the correct use of the "this" keyword. Nested functions
are essentially methods and parent functions are classes.

You could not be more wrong.

1. There are no pointers in JavaScript, and object references are not
compareable to C(++/#) pointers.

2. JavaScript as implemented from NN4 to current Mozilla/5.0-based browsers,
and JScript as implemented in IE is a programming language supporting
prototype-based inheritance; there are no classes.

3. Maybe you are referring to JScript.NET for ASP.NET/IIS which also
supports class-based inheritance, however that is not JavaScript.
As long as i rememebr this then the use of the "this" keywork is
exactly the same as in c#.

No, it is not.

<URL:http://msdn.microsoft.com/library/en-us/csref/html/vclrfThisPG.asp>
<URL:http://msdn.microsoft.com/library/en-us/jscript7/html/jsstmthis.asp>
<URL:http://http://developer.mozilla.org..._New_Objects:Using_this_for_Object_References>
<URL:http://developer.mozilla.org/js/specs/ecma-262#a-10.1.7>


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
[...]
2. JavaScript as implemented from NN4 to current Mozilla/5.0-based
browsers,

That should have been NN2 instead, of course.
and JScript as implemented in IE is a programming language supporting
prototype-based inheritance; there are no classes.


PointedEars
 
J

John G Harris

Ears recommends that ...
Identifiers not referring to functions used as constructors should not start
with an uppercase letter in order to avoid confusion and undesired side
effects.
....but, of course, if you have an alternative scheme for avoiding
confusion then feel free to use it.

John
 

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,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top