2016-02-19 10 views
6

Ich habe versucht, Variable fullName nach dem Ausführen der Funktion zu trösten, aber es hat den Wert nicht geändert, nur Konsolenstandardwert Not Set, warum war das?Instanzfunktionsvariable wird nicht geändert?

function Test() { 
    this.clientData = { 
     fullName : "Not Set", 
     setUserName: function (firstName, lastName) { 
      this.fullName = firstName + " " + lastName; 
     }, 
     getUserInput2: function (firstName, lastName, callback) { 
      callback(firstName, lastName); 
     } 
    }; 

    this.getUserInput1 = function (firstName, lastName, callback) { 
     callback(firstName, lastName); 
    }; 
} 

var test = new Test(); 

test.getUserInput1("A1", "B1", test.clientData.setUserName); 

console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
//expected => A1 B1 

test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName); 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
//expected => A2 B2 
+2

Möglicherweise ein Duplikat von [* 'this' in Callback-Funktionen *] (http://stackoverflow.com/questions/14561723/this-in-callback-functions).Vielleicht möchten Sie auch lesen [* Wie funktioniert das "dieses" Schlüsselwort? *] (Http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work/3127440#3127440) und [ * MDN: this *] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this). – RobG

Antwort

2

Arbeits Dies verwendet. Sie können dies tun, ohne die Funktion bind() zu verwenden. Sie müssen nur Testobjekt in Variable speichern.

function Test() { 
 
var t = this 
 
this.clientData = { 
 
      fullName : "Not Set", 
 
      setUserName: function (firstName, lastName) { 
 
      t.clientData.fullName = firstName + " " + lastName; 
 
      }, 
 
      getUserInput2: function (firstName, lastName, callback) { 
 
       callback(firstName, lastName); 
 
      } 
 
     }; 
 
this.getUserInput1 = function (firstName, lastName, callback) { 
 
    callback(firstName, lastName); 
 
     }; 
 
} 
 

 
var test = new Test(); 
 
test.getUserInput1("A1", "B1", test.clientData.setUserName); 
 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
 
//expected => A1 B1 
 
test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName); 
 
console.log("test.clientData.fullName : " + test.clientData.fullName);//Not Set 
 

+0

Ich denke, dass Sie wollen, dass das 'var t = this;' – Pevara

+0

Vielen Dank @Pevara für einen Zeigefehler –

3

Es liegt daran, dass, wenn die Rückrufe genannt werden, der Kontext (this) Wert des Rückrufs nicht das clientData Objekt ist.

können Sie den Rückruf gesetzt manualy Function.bind()

function Test() { 
 
    this.clientData = { 
 
    fullName: "Not Set", 
 
    setUserName: function(firstName, lastName) { 
 
     this.fullName = firstName + " " + lastName; 
 
    }, 
 
    getUserInput2: function(firstName, lastName, callback) { 
 
     callback(firstName, lastName); 
 
    } 
 
    }; 
 
    this.getUserInput1 = function(firstName, lastName, callback) { 
 
    callback(firstName, lastName); 
 
    }; 
 
} 
 

 
var test = new Test(); 
 
var userInput = new test.getUserInput1("A1", "B1", test.clientData.setUserName.bind(test.clientData)); 
 
snippet.log("test.clientData.fullName : " + test.clientData.fullName); //Not Set 
 
//expected => A1 B1 
 
test.clientData.getUserInput2("A2", "B2", test.clientData.setUserName.bind(test.clientData)); 
 
snippet.log("test.clientData.fullName : " + test.clientData.fullName); //Not Set 
 
//expected => A2 B2
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

+0

Erklären Sie ein wenig über '.bind()' .. + 1 – Rayon

+0

Eine Funktion * this * ist nur ein Parameter des Ausführungskontext, es ist nicht ** der ** Kontext. Das OP-Problem besteht darin, dass der Rückruf * this * nicht auf den richtigen Wert eingestellt ist, also das, was behoben werden muss (durch Bind, eine Schließung oder Ändern des Anrufs). – RobG

3

Um deutlich über die this Aussage zu verstehen, müssen Sie verstehen, dass es den aktuellen „scope“ innerhalb der Funktion darstellt.

Wenn Sie erklären:

function Test() { 
    this.clientData = { 
    .... 
    }; 
} 

this stellt den aktuellen Umfang der Test Funktion. Wenn Sie also var test = new Test(); ausführen, können Sie test.clientData verwenden und dann auf die Daten zugreifen, die Sie bei der Initialisierung Ihres Objekts festgelegt haben.

nun in Ihrem clientData Eigentum Ihrer test Objekt, Sie haben ein setUserName (Ich empfehle Ihnen, es zu nennen setFullName), die wiederum eine Funktion (JavaScript is function scoped). Wenn wir also auf dem Code aussehen:

function Test() { 
    this.clientData = { 
     fullName: "Not Set", 
     setFullName: function(firstName, lastName) { 
      /* 
      * `this` represents the scope of the `setFullName` function, 
      * and not the scope of the `Test` function 
      */ 
      this.fullName = firstName + " " + lastName; 
     } 
    }; 
} 

so der Trick this in einer Variablen in der obersten Ebene zu speichern, weil JavaScript-Funktion scoped ist, wird die Variable für jede Funktion innerhalb des Schutzbereiches zur Verfügung. So, jetzt können wir das tun:

function Test() { 
    var self = this; 
    self.clientData = { 
     fullName: "Not Set", 
     setFullName: function(firstName, lastName) { 
      self.clientData.fullName = firstName + " " + lastName; 
     } 
    }; 
} 

Ich empfehle Ihnen, Ihre Daten und Ihre Methode auf eine andere Weise zu spalten. Jetzt fügen Sie alles in ein clientData Objekt ein, das Ihrer App Komplexität hinzufügt. Sie können die gespeicherten Werte (Name, Alter, Speicherinformationen) und die Methoden, die mit den Daten interagieren, trennen.

Ich schlage vor, so etwas wie das:

function Person() { 
 
    var self = this; 
 
    self.fullName = "Not Set" 
 
    self.setFullName = function(firstName, lastName) { 
 
     self.fullName = firstName + " " + lastName; 
 
    }; 
 
} 
 
var john = new Person(); 
 
john.setFullName("John", "Doe"); 
 
console.log("john.fullName : " + john.fullName); // Display : John Doe 
 
var bruce = new Person() 
 
bruce.setFullName("Bruce", "Wayne"); 
 
console.log("bruce.fullName : " + bruce.fullName); // Display : Bruce Wayne

So kann man viel leichter Code zu lesen und ein viel einfacher Code auszuführen. Danach liegt es an Ihnen, Ihre Objektlogik so zu organisieren und zu gestalten, wie Sie es möchten.

Hoffe es hilft.

Verwandte Themen