2016-03-28 10 views
0

Ich schreibe eine Javascript-App, wo ich auf meine Anwendungsvariablen auf globaler Ebene zugreifen möchte. Etwas wie folgt aus:Javascript Zugriff Mitglied Variablen durch Referenz

//Initialize 
var myApp=new app(); 

//Count is zero here, as expected since app is asynchronous 
console.log(myApp.count); 

//But 5 seconds later, count should have a non-zero value 
setTimeout(function(){ 
    console.log(myApp.count); 
}, 5000); 

Und der Anwendungscode:

//Application code 
function app() { 

    var count=0; 

    setTimeout(function(){ 
     console.log("Setting count to 10"); 
     count=10; 
    }, 2500); 

    //Member variable for count 
    this.count=count; 
} 

die jsfiddle Siehe hier: https://jsfiddle.net/o4db2ep4/

Was ich will, ist für den ersten Zugriff des Grafen Null zu sein, aber die zweite sollte 10 sein.

Ich denke, was passiert ist, dass zu der Zeit, die ich myApp deklariere, erhält es den Wert für die Zählung als Null . Es ist wie ein Wert-Referenz-Problem, kombiniert mit einem Scope, und ich habe damit zu kämpfen.

Wie kann ich einen Verweis auf app.count erhalten, der dynamisch ist, d. H. Immer die aktuellen Werte von count und nicht den Wert zum Zeitpunkt der Zuweisung enthält? Wenn dies nicht möglich ist, wie sollte ich dieses Problem überdenken?

+1

'setTimeout' Pause nicht das Skript. Es plant nur die Funktion, die Sie bereitstellen, damit es später ausgeführt wird, also wird 'this.count = count' ausgeführt, lange bevor der' setTimeout' Callback ausgeführt wird. –

+0

Ja, das verstehe ich. Wenn jedoch app.count ein Zeiger auf this.count ist, verweisen sie immer auf die gleichen Werte, unabhängig davon, wann sie ausgeführt werden. – jrel

+1

JavaScript ist streng pass/zuweisen nach Wert. Eine Variable/Eigenschaft kann nicht auf eine andere Variable/Eigenschaft verweisen. –

Antwort

1

Was passiert ist, dass count und this.count verschiedene Variablen sind, und sie sind nicht magisch synchron. Sobald Sie es zugewiesen haben, ist es eine einmalige Sache. Wenn es zugewiesen wird this.count=count=0; das Timeout wird passieren 2500ms nach, an dem dieser Punkt, was Sie aktualisieren möchten ist this.count:

function app() { 

    this.count = 0; 

    setTimeout(function(){ 
     console.log("Setting count to 10"); 
     this.count = 10; 
    }.bind(this), 2500); 
} 

Sie müssen nicht beide Variablen wie Sie oben sehen können.

+0

Danke, das ist hilfreich. Es ist die .bind (diese), die die wahre Magie tut, und dies löst das Problem. Aber ich muss zugeben, ich bin mir nicht sicher, was genau es macht. – jrel

1

Wie wäre es damit:

//Initialize 
var myApp=new app(); 
myApp.increment(myApp); 

//Count is zero here, as expected since app is asynchronous 
console.log(myApp.count); 

//But 5 seconds later, count does have a non-zero value 
setTimeout(function(){ 
    console.log(myApp.count); 
}, 5000); 


//Application code 
function app() { 

    this.count=0; 

    this.increment = function(obj) { 
     setTimeout(function(){ 
      console.log("Setting count to 10"); 
      if (typeof(obj.count)=='undefined') { obj.count=0;} 
      obj.count+=10; 
     }, 2500);  
    } 
} 
+0

Das ist auch hilfreich, danke. – jrel