2016-05-06 11 views
1

Problem:keine Funktion Typeerror beim Aufruf von Objektmethode in Javascript

Wenn ich versuche, eine Objektmethode in dieser besonderen Art und Weise in JavaScript zu nennen, erhalte ich folgende Fehlermeldung:

TypeError: listener.update is not a function 

Mein Code:

<html> 
<head> 
<script src="library.js"></script> 
</head> 
<body> 
<script> 

// manages listeners etc. 
function Model() { 
    var listeners = []; 

    this.addListener = function(listener) { 
     listeners.push(listener); 
    }; 

    // the model will call the listeners when "setting the selection" 
    this.setSelection = function() { 
     for (listener in listeners) 
      listener.update(); 
    }; 
}; 

// test function that will be used as update 
function moveon() { 
    var answer = confirm("Ready to move on?"); 
    if (answer) window.location = "http://google.com"; 
} 

// create a model and add a listener 
var model = new Model(); 
var listnr = {}; 
listnr.update = moveon; 
model.addListener(listnr); 
// update listener 
setTimeout(model.setSelection, 2000); // this doesn't work 
// setTimeout(listnr.update, 2000); // but this does 

</script> 
</body> 
</html> 

Erklärung des Codes:

Die Model Objekt verwaltet eine Liste von listeners und fordert ihre update Methode, wenn einige Zustand geändert hat. In meinem Beispiel passiert das, wenn setSelection aufgerufen wird.

Hinweis:

Der Fehler ist nicht sehr aufschlussreich, und wenn ich die letzte Zeile Kommentar-, listnr.update funktioniert gut.

Frage:

Warum erhalte ich diese Fehlermeldung, wenn das Verfahren aus dem Modell genannt wird, und/oder wie kann ich lösen dieses Problem?

+0

Bitte verwenden Sie einen Debugger, bevor Sie zu SO gehen –

+1

Wie so? Was würde ich mit einem Debugger herausfinden? Und was ist SO? : p – Sebi

+0

Sie könnten Ihr Listener-Objekt überprüfen und sehen, was es ist update -Eigenschaft ... –

Antwort

2

model.setSelection behält den Verweis auf das Objekt nicht. Wenn Sie älteren Browser nicht unterstützen, müssen Sie sie binden zum Objekt:

model.setSelection.bind(model) 

Wenn Sie älteren Browser brauchen zu kümmern, können Sie nur eine kleine anonyme Funktion verwenden:

function() { model.setSelection(); } 

Beide Methoden behalten die Objektreferenz bei, die für setSelection erforderlich ist.

Der Grund listnr.update funktioniert, weil das nicht der gleiche Typ der Funktion ist; Sie haben eine eigenständige Nicht-Objekt-Funktion erstellt und nur einen Verweis darauf in das Objekt gesetzt, so dass es gut funktioniert. Aber wenn Sie das mit dem Modell ausprobieren würden, könnten Sie das Objekt selbst nicht aktualisieren.

+0

Es tut mir leid, aber ich verstehe immer noch nicht ganz, und ich kann es nicht zu arbeiten, indem Sie binden, wie Sie vorschlagen noch auf andere Weise versuchte ich es. Also, wenn Sie eine Funktion an ein Objekt übergeben wollen, müssen Sie alles binden, auf das sich die Funktion bezieht oder so ähnlich? Ich bin ein wenig enttäuscht von JavaScript, weil das nicht sehr nett ist, wenn Sie Funktionen höherer Ordnung verwenden möchten. – Sebi

+1

Dies ist nur ein Problem, wenn Sie versuchen, Mitgliederfunktionen selbständig zu übergeben, wie Sie es in setTimeout versuchen. 'setTimeout (function() {model.setSelection();}, 2000) sollte mit dem, was Sie eingefügt haben, gut funktionieren. –

+0

Ok, danke ich habe es jetzt endlich geschafft! Ihre Lösung funktioniert in der Tat! – Sebi

Verwandte Themen