Passing an object while dynamically calling a function

Discussion in 'Javascript' started by sfeher@gmail.com, Jun 28, 2006.

  1. Guest

    Hi All,

    I need to call a function(loaded with appendChild) for which I have the
    name as a string.

    ....
    var fnName = 'fn1';
    var call = fnName + '('+ param +' )';
    eval(call);

    It works fine as long as the param is a string but when I try to pass
    an object it does not work as toString kicks in. Is there a better way
    of doing this other than eval? How can I pass an object to fn1? I
    thought about marshalling but I hope there's a better way inside the
    language. Can someone help me understand this?

    Regards,
    Sebastian
     
    , Jun 28, 2006
    #1
    1. Advertising

  2. Guest

    To clarify this - I do not expect eval to work on anything but string.
    That said, my hope is that Javascript has a way of getting a reference
    to a function "by name" so I can avoid the need of marshalling and
    using eval.

    wrote:
    > Hi All,
    >
    > I need to call a function(loaded with appendChild) for which I have the
    > name as a string.
    >
    > ...
    > var fnName = 'fn1';
    > var call = fnName + '('+ param +' )';
    > eval(call);
    >
    > It works fine as long as the param is a string but when I try to pass
    > an object it does not work as toString kicks in. Is there a better way
    > of doing this other than eval? How can I pass an object to fn1? I
    > thought about marshalling but I hope there's a better way inside the
    > language. Can someone help me understand this?
    >
    > Regards,
    > Sebastian
     
    , Jun 28, 2006
    #2
    1. Advertising

  3. RobG Guest

    wrote:
    > To clarify this - I do not expect eval to work on anything but string.
    > That said, my hope is that Javascript has a way of getting a reference
    > to a function "by name" so I can avoid the need of marshalling and
    > using eval.


    Please don' t top-post, now everyone has to scroll down to the bottom
    to see what you are talking about, then come back to the top to see the
    reply.

    All functions declared in a global scope are properties of the global
    object. JavaScript provides two methods for getting references to
    object properties - dot notation and square bracket notation.

    To reference a global function using square bracket notation:

    function foo() {...}

    window['foo']();


    To use a varaible:

    var bar = 'foo';
    window[bar](); // calls foo();


    You use dot notation where the string supplied is the name of the
    property you want to access (e.g. window.foo() in the above) and use
    use square bracket notation when you want the supplied parameter to be
    evaluated - 'foo' evaluates to foo, as does bar.

    One final note, the window object may not be available in every user
    agent that runs your script, so you might want to use the global object
    instead (they are synonymous in browsers):

    // Declare in global scope:
    var _global = this;


    Now use _global wherever you would have used window.

    >
    > wrote:
    > > Hi All,
    > >
    > > I need to call a function(loaded with appendChild) for which I have the
    > > name as a string.


    How do you load a function using appendChild? Or do you load the
    script element containing the function using appendChild?


    > > var fnName = 'fn1';
    > > var call = fnName + '('+ param +' )';


    call is a method of the Function object, so not really a good name for
    a variable (personal preference). To do what you want here (without
    eval):

    var _global = this;
    var fnName = 'fn1';
    var call = _global[fnName];

    call is now a reference to the (presumably) function object fn1, and
    call() should execute it.

    > > eval(call);
    > >
    > > It works fine as long as the param is a string but when I try to pass
    > > an object it does not work as toString kicks in. Is there a better way
    > > of doing this other than eval? How can I pass an object to fn1? I


    You never 'pass an object' - you always 'pass' a reference to an
    object.

    A fundamental principle of JavaScript is that where a variable is
    assigned a primitive value, then:

    var a = 5;
    var b = a;

    Both a and b now have a value of 5, it is effectively copied to b.
    Modifying the value of a will not have any effect on the value of b.

    When a variable is assigned a value that is a reference to an object,
    then:

    var objA = new Object();
    var objB = objA;

    The value of objA is a *reference* to the object, so the reference is
    copied to the value of objB. objA and objB now reference the same
    object. Therefore modifying (the object referenced by) objA will also
    modify (the object referenced by) objB - it is the same object.

    So wherever the value of a variable is assigned to some other variable
    ( var b = a) its value is always copied, just that sometimes it is a
    primitive value and other times it is a reference to an object. You
    may hear the saying 'primitives are passed by value, objects are passed
    by reference' - don't believe it, for me it completely obfuscated what
    is really happening.


    > > thought about marshalling but I hope there's a better way inside the
    > > language. Can someone help me understand this?


    I hope I did! :)

    If not, please let me know.

    --
    Rob
     
    RobG, Jun 28, 2006
    #3
  4. Guest

    RobG wrote:
    > wrote:
    > > To clarify this - I do not expect eval to work on anything but string.
    > > That said, my hope is that Javascript has a way of getting a reference
    > > to a function "by name" so I can avoid the need of marshalling and
    > > using eval.

    >
    > Please don' t top-post, now everyone has to scroll down to the bottom
    > to see what you are talking about, then come back to the top to see the
    > reply.


    My apologies... one more thing to know :)
    Not to blame it on Google Groups but probably they should discourage
    this by not placing the cursor at the top of the textarea on replies ..

    >
    > All functions declared in a global scope are properties of the global
    > object. JavaScript provides two methods for getting references to
    > object properties - dot notation and square bracket notation.
    >
    > To reference a global function using square bracket notation:
    >
    > function foo() {...}
    >
    > window['foo']();
    >
    >
    > To use a varaible:
    >
    > var bar = 'foo';
    > window[bar](); // calls foo();
    >
    >
    > You use dot notation where the string supplied is the name of the
    > property you want to access (e.g. window.foo() in the above) and use
    > use square bracket notation when you want the supplied parameter to be
    > evaluated - 'foo' evaluates to foo, as does bar.
    >
    > One final note, the window object may not be available in every user
    > agent that runs your script, so you might want to use the global object
    > instead (they are synonymous in browsers):
    >
    > // Declare in global scope:
    > var _global = this;
    >
    >
    > Now use _global wherever you would have used window.
    >
    > >
    > > wrote:
    > > > Hi All,
    > > >
    > > > I need to call a function(loaded with appendChild) for which I have the
    > > > name as a string.

    >
    > How do you load a function using appendChild? Or do you load the
    > script element containing the function using appendChild?


    Right, it's the script that contains the function that gets loaded.

    >
    >
    > > > var fnName = 'fn1';
    > > > var call = fnName + '('+ param +' )';

    >
    > call is a method of the Function object, so not really a good name for
    > a variable (personal preference). To do what you want here (without
    > eval):
    >
    > var _global = this;
    > var fnName = 'fn1';
    > var call = _global[fnName];
    >
    > call is now a reference to the (presumably) function object fn1, and
    > call() should execute it.


    Excellent! Thanks Rob.

    >
    > > > eval(call);
    > > >
    > > > It works fine as long as the param is a string but when I try to pass
    > > > an object it does not work as toString kicks in. Is there a better way
    > > > of doing this other than eval? How can I pass an object to fn1? I

    >
    > You never 'pass an object' - you always 'pass' a reference to an
    > object.
    >
    > A fundamental principle of JavaScript is that where a variable is
    > assigned a primitive value, then:
    >
    > var a = 5;
    > var b = a;
    >
    > Both a and b now have a value of 5, it is effectively copied to b.
    > Modifying the value of a will not have any effect on the value of b.
    >
    > When a variable is assigned a value that is a reference to an object,
    > then:
    >
    > var objA = new Object();
    > var objB = objA;
    >
    > The value of objA is a *reference* to the object, so the reference is
    > copied to the value of objB. objA and objB now reference the same
    > object. Therefore modifying (the object referenced by) objA will also
    > modify (the object referenced by) objB - it is the same object.
    >
    > So wherever the value of a variable is assigned to some other variable
    > ( var b = a) its value is always copied, just that sometimes it is a
    > primitive value and other times it is a reference to an object. You
    > may hear the saying 'primitives are passed by value, objects are passed
    > by reference' - don't believe it, for me it completely obfuscated what
    > is really happening.


    My understanding is that it's pretty similar to Java where everything
    gets passed "by value", which in the case of non-primitive values is
    actually "the value of the reference".

    It means you can change the value of the reference but not the
    reference itself (similar to the C++ pass by pointer).

    It's quite tricky when it comes to passing Javascript functions along,
    I don't get that yet either..

    >
    >
    > > > thought about marshalling but I hope there's a better way inside the
    > > > language. Can someone help me understand this?

    >
    > I hope I did! :)
    >
    > If not, please let me know.
    >
    > --
    > Rob


    You sure did :)

    Thank you,
    Sebastian
     
    , Jun 28, 2006
    #4
  5. writes:

    > Hi All,
    >
    > I need to call a function(loaded with appendChild) for which I have the
    > name as a string.
    >
    > ...
    > var fnName = 'fn1';
    > var call = fnName + '('+ param +' )';
    > eval(call);
    >
    > It works fine as long as the param is a string but when I try to pass
    > an object it does not work as toString kicks in.


    I'm surprised that the string works. It should only work for values
    that has string representations that are also literal expressions
    of the value (number, boolean, null, undefined and probably also
    functions).

    > Is there a better way of doing this other than eval?


    If you have the name of the function, and that is the name
    it is available as in the global scope, you can either do
    global scope lookup or use eval. In either case, only do
    it on the function name and do the call directly. No need
    to create a string containing the call and the evaluate it.

    I.e., either (e.g.):

    function globalVar(name) {
    return this[name];
    }
    globalVar(fnName)(param);

    or

    eval(fnName)(param);

    > How can I pass an object to fn1?


    The same way you would always do it: call the function. Going through
    a string representation of a call is a detour, not a shortcut :)

    /L
    --
    Lasse Reichstein Nielsen -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Jun 28, 2006
    #5
  6. JRS: In article <>,
    dated Wed, 28 Jun 2006 08:03:18 remote, seen in
    news:comp.lang.javascript, posted :

    >My apologies... one more thing to know :)
    >Not to blame it on Google Groups but probably they should discourage
    >this by not placing the cursor at the top of the textarea on replies ..


    The cursor should be put at the top, because it facilitates removing
    those parts that need not be quoted; putting it at the bottom would
    encourage untrimmed quoting.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; Win98. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
    PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
    My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.
     
    Dr John Stockton, Jun 29, 2006
    #6
    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. James Vanns
    Replies:
    7
    Views:
    7,133
    Evan Carew
    Jan 21, 2004
  2. Andreas Lagemann
    Replies:
    8
    Views:
    517
    Mike Wahler
    Jan 10, 2005
  3. tiwy
    Replies:
    0
    Views:
    457
  4. Petri Savolainen
    Replies:
    0
    Views:
    454
    Petri Savolainen
    Jul 1, 2003
  5. Richard A. DeVenezia
    Replies:
    4
    Views:
    153
    Lasse Reichstein Nielsen
    Sep 5, 2003
Loading...

Share This Page