javascript passing by reference problem

Discussion in 'Javascript' started by ged, Dec 18, 2005.

  1. ged

    ged Guest

    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>
    ged, Dec 18, 2005
    #1
    1. Advertising

  2. ged wrote:

    > 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]

    <URL:http://jibbering.com/faq/#FAQ4_43>

    > <!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. <URL:http://validator.w3.org/>

    > [...]


    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
    Thomas 'PointedEars' Lahn, Dec 18, 2005
    #2
    1. Advertising

  3. ged wrote:
    > 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:-

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


    > 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">

    <snip>
    > 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.
    Richard Cornford, Dec 18, 2005
    #3
  4. ged

    ged Guest

    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
    ged, Dec 18, 2005
    #4
  5. ged wrote:

    > 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/en/docs/Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_this_for_Object_References>
    <URL:http://developer.mozilla.org/js/specs/ecma-262#a-10.1.7>


    PointedEars
    Thomas 'PointedEars' Lahn, Dec 18, 2005
    #5
  6. Thomas 'PointedEars' Lahn wrote:

    > [...]
    > 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
    Thomas 'PointedEars' Lahn, Dec 18, 2005
    #6
  7. In article <>, Thomas 'PointedEars'
    Lahn <> writes

    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
    --
    John Harris
    John G Harris, Dec 19, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sam pal
    Replies:
    3
    Views:
    537
    E. Robert Tisdale
    Jul 16, 2003
  2. Thomas Christmann

    Problem with passing dynamic arrays by reference

    Thomas Christmann, Aug 31, 2004, in forum: C Programming
    Replies:
    3
    Views:
    403
    Martin Ambuhl
    Aug 31, 2004
  3. Davide Bruzzone
    Replies:
    2
    Views:
    239
    Davide Bruzzone
    Aug 4, 2003
  4. Replies:
    2
    Views:
    144
  5. nick
    Replies:
    20
    Views:
    262
Loading...

Share This Page