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

2.9k views Asked by At

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!');
     });
}
4

There are 4 answers

3
zmo On BEST ANSWER

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.

0
nalinc On

window.myHub is being passed as undefined to SignalRSetUp() since you havnt initialized it before passing.

window.myHub = "default value";

More importantly, since myHub is global to window scope, you dont need to pass it in the function. It'll be available in SignalRSetUp() straightaway.

Cheers!

3
rajasaur On

You are passing by value when sending in window.myHub. Send in the parameter as "window" if you want to have pass by reference.

For e.g.

SignalRSetup(argObj,eventFuncs,globalVar) {
       .....
       globalVar.myHub = hub
}

var signalRSetUp = new SignalRSetUp(args,callBackFuncs, window);
// Now window.myHub will have the value from the method

A good reference is here

0
RobG On

You can do it by passing the name of the variable, then accessing it as a property of the global object, so:

// Create global
var myHub;
var globalObj = this;

// Pass property name as a string and object to resolve it on 
// as a reference
var signalRSetUp = new SignalRSetUp(args,callBackFuncs, 'myHub', globalObj);

// Resolve in callback
function SignalRSetUp(argObj, eventFuncs, globalVarName, globalVarObj)
{
    ...
            .done(function () {
                globalVarObj[globalVarName] = hub;
            })
    ...
}

You could not pass the global object and just assume it's the same one (probably extremely likely but if you use frames might be required) but you might want to change it to some other object to avoid the global, in which case you might just pass the object around and maybe also give it a method to get and set the property.