2015-06-12 4 views
2

Мне нужна глобальная переменная «window.myHub» для установки, которая передается как параметр функции (SignalRSetUp), как показано ниже: способ, которым он передается прямо сейчас , не устанавливает! Как это можно решить?Как передать глобальную переменную как параметр по ссылке в javascript

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

* Window.myHub * имеет значение * undefined *, так что это значение, которое вы передаете * SignalRSetUp * и присваивается * globalVar *. Вы не можете передать ссылку на переменную, вы можете передать ее только значение (отметив, что при назначении объекта переменной назначенное значение является ссылкой на объект). – RobG

+0

, пожалуйста, установите window.myHub = {}; а затем посмотреть результат –

+0

Зачем вам это делать вообще? Почему вы не можете просто «вернуть хаб» из этой функции? – Bergi

ответ

2

Javascript всегда работает с передачей по значению. И когда вы даете window.myHub в качестве параметра функции, вы фактически получаете ссылку на объект (значение) в памяти, указанную window.myHub.

Но что не работает в вашем коде, является то, что вы переназначение ссылочный объект в памяти, на который указывает globalVar:

globalVar = hub; 

, который затем globalVar со ссылкой на то, что в ступице. т. е .: вы не меняете значение упомянутого значения, вы меняете то, на что оно указывает.

Если вы:

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

, а затем в коде:

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

тогда вы будете заменить эталонное значение элемента myHub внутри объекта aWindow.

Учитывая, что window.myHub является содержащий undefined, то, что вы на самом деле проходит undefined в globalVar, а затем изменить, где globalVar указывает на:

вот переменные при запуске:

memory: [xxxxxxxxxxx] 
      ^
       | 
     window.myHub 

Тогда вы вызывать функцию SingalRSetUp:

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

Тогда вы назначаете что-то еще globalVar:

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

Когда я предлагаю вам пройти какой-либо изменяемый объект (является ли массив, или объект), то вы можете использовать тот факт, что вы» повторно ссылается данный объект по всей программе, и он будет нести ответственность, чтобы быть своего рода «реестр» (может быть, мы можем найти лучшее слово для этого) правильных ссылок:

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

Тем не менее, вся цель глобальной переменной, такой как окно, - это доступ к ней из любого места в проге ram, и вы могли бы просто не передавать его в качестве параметра, как предлагает @NLN, вы можете просто получить к нему доступ из функции.

+0

очень хорошо объяснено – user2837167

+0

SignalRSetup() - это общий метод, поэтому любой может использовать его, если вы передадите ему намеченные параметры. Поэтому он не знал, какой вызывающий объект хочет установить глобальную переменную. Следовательно, мы хотели бы отправить именно как параметр. – user2837167

+0

«Javascript всегда работает с проходом по ссылке» Неправильно. JavaScript ВСЕГДА проходит по значению, точно так же, как Java. В JavaScript нет сквозной ссылки. То, что вы описали, - это именно то, что означает «пропускная способность». – newacct

2

window.myHub в настоящее время передается в undefined к SignalRSetUp(), так как вы havnt инициализируется его перед передачей.

window.myHub = "default value"; 

Что еще более важно, так как myHub глобальна для window сферы, вам не нужно передать его в функцию. Он будет доступен в SignalRSetUp() сразу.

Cheers!

2

Вы отправляете по значению при отправке в window.myHub. Отправьте параметр как «окно», если вы хотите пройти по ссылке.

См., Например,

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

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

Хорошая ссылка here

+0

хорошо, технически то, что вы говорите правильно, но даже если оно * выглядит * как пропуск по значению, статья, которую вы имеете в виду неправильно. Javascript * всегда * передавать по ссылке любую переменную. Просто примитивные типы переменных неизменяемы. Когда вы выполняете задание, вы не меняете ссылочный объект, вы заменяете то, что ссылается на переменную, эффективно освобождая исходный объект, заменяя его новым. Поскольку упомянутый объект был разделен между вызывающим и вызываемым абонентами, как только вы его потеряете, вы потеряете свою «ссылку» с вызывающим. – zmo

+0

@zmo: НЕТ, JavaScript ВСЕГДА проходит по значению. Всегда. Так же, как Java. В JavaScript нет доступа к ссылке. То, что вы описали, - это именно то, что означает «пропускная способность». – newacct

+0

Черт, я не собираюсь удалять этот комментарий, но повторное чтение показывает, насколько я ошибался. Спасибо за исправление и mea culpa! ;-) – zmo

1

Вы можете сделать это, передавая имя переменной, то доступ к нему как свойство глобального объекта, так:

// 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; 
      }) 
    ... 
} 

Вы могли бы не пропускайте глобальный объект и просто предположите, что он один и тот же (возможно, очень вероятно, но если вы используете кадры, возможно, потребуется), но вы можете изменить его на какой-то другой объект, чтобы избежать глобального, и в этом случае вы можете просто передать объект вокруг и, возможно, также дать это способ получить и установить свойство.

+0

Perfect. Спасибо, это работает. – user2837167

Смежные вопросы