Search code examples
javascriptpass-by-reference

How to pass a global variable as parameter by reference in javascript


I need a global variable "window.myHub" to set which is passed on as parameter to a function(SignalRSetUp) as below: The way it is passed on right now, doesn't set it ! How could this be resolved ?

var args = {
            "userObjectId": UserObjectId,
            "hubURL": LCSHubApiURL,
            "hubName": HubProxyName,
};
var callBackFuncs = {
            "ping": PingFunc
};

window.myHub;
var signalRSetUp = new SignalRSetUp(args,callBackFuncs, window.myHub);

SignalRSetUp(argObj,eventFuncs,globalVar)
{
     var $self = this;
     var connection = $.hubConnection(argObj.hubURL);
     var hub = connection.createHubProxy(argObj.hubName);
     hub.connection.qs = { "objectid": argObj.userObjectId };

     //Wire : Call back functions and the Hub events
     for (var e in eventFuncs) {
         hub.on(e, eventFuncs[e]);
         //hub event fail
     }

     connection.start()
     .done(function () {
         globalVar = hub;
     }).fail(function (error) {
         console.log('Could not Connect!');
     });
}

Solution

  • Javascript always work with pass by value. And when you give window.myHub as parameter to the function, you actually get a reference to the object (value) in memory referred by window.myHub.

    But what's not working in your code, is that you're reassigning the referenced object in memory pointed by globalVar:

    globalVar = hub;
    

    which then has globalVar referring to whatever is in hub. i.e.: you're not changing the value of the referred value, you're changing what it points to.

    If you do:

    var signalRSetUp = new SignalRSetUp(args,callBackFuncs, window);
    

    and then in your code:

    SignalRSetUp(argObj,eventFuncs,aWindow) {
        //...
        aWindow.myHub = hub;
        //...
    }
    

    then you'll be replacing the referenced value of the member myHub within the object aWindow.

    Considering that window.myHub is containing undefined, then what you actually do is passing undefined as globalVar, and then changing where globalVar points to:

    here's your variables when you start:

    memory: [xxxxxxxxxxx]
                  ^
                  |
             window.myHub
    

    Then you call the function SingalRSetUp:

              globalVar
                  |
                  v
    memory: [xxxxxxxxxxx]
                  ^
                  |
             window.myHub
    

    Then you assign something else to globalVar:

                         globalVar
                             |
                             v
    memory: [xxxxxxxxxxx|yyyyyyyyyyy]
                  ^
                  |
             window.myHub
    

    When I suggest that you pass any sort of mutable object (whether this is an array, or an object), then you can use the fact that you're referencing this object throughout your program, and it will be responsible to be some sort of "registry" (maybe can we find a better word for that) of the right references:

              aWindow     aWindow.myHub
                  |          |
                  v          v
    memory: [xxxxxxxxxxx|yyyyyyyyyyy]
                  ^          ^
                  |          |
                window    window.myHub
    

    That said, the whole purpose of a global variable — such as window — is that it can be accessed from any place in the program, and you could simply avoid to pass it as a parameter, as @NLN suggests, you can simply access it from within the function.