2010-02-12 20 views
7

Ich habe eine JavaScript-Klasse, die wie folgt aussieht:Umfang „this“ in JavaScript

function SomeFunction() 
{ 
    this.doSomething(function() 
    { 
     this.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Dieser Code einen Fehler wirft, weil der Umfang der „this“ innerhalb der Funktion, die in doSomething() übergeben ist anders als der Bereich von "this" außerhalb dieser Funktion.

Ich verstehe, warum das ist, aber was ist der beste Weg, damit umzugehen? Das ist, was ich am Ende mache:

function SomeFunction() 
{ 
    var thisObject = this; 

    this.doSomething(function() 
    { 
     thisObject.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 

Das funktioniert gut, aber es fühlt sich einfach an wie ein Hack. Ich frage mich nur, ob jemand einen besseren Weg hat.

+2

@Jon Kruger Das mache ich auch. Ich denke, das ist ziemlich normal. Sie können "this" mit "call" und "apply" ändern, aber das passt nicht immer zu dem, was Sie gut machen. Eine andere Option ist es, 'this' als Parameter zu übergeben, aber das fühlt sich eher wie ein Hack an. –

+0

@ Jonathon Was meinen Sie mit "Sie können dies mit Anruf ändern und anwenden"? –

+1

@Jon Kruger Siehe hierzu auch ihren Artikel für 'call': https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply –

Antwort

10

Das ist die richtige und allgemein akzeptierte Problemumgehung. Es ist eine Art Kludgie, aber das machen alle. Typischerweise wird diese zusätzliche Variable self, wie es in dem Namen:

function SomeFunction() 
{ 
    var self = this; 

    this.doSomething(function() 
    { 
     self.doSomethingElse(); 
    }); 

    this.doSomethingElse = function() 
    { 

    } 
} 
+1

Beachten Sie, dass "self" eine Eigenschaft des window-Objekts in Browsern ist, die auf sich selbst zeigt, obwohl dies wahrscheinlich keine Probleme verursacht. –

+0

Andere Namen, die ich ziemlich oft benutzt habe, sind 'that' und' me', je nach Kontext. – cHao

3

this dynamisch "scope" hat. Das bedeutet, dass es von dem angelegt wird, was es bindet, und this ist durch einen "Methodenaufruf" gebunden. Das heißt, jede Zeit in Ihrem Programm, das Sie sehen dies: w.f() dann während f ausgeführt wird, wird this dynamisch gebunden f, sogar wenn f hatte this in seinem lexikalischen Gültigkeitsbereich.

Die meisten JavaScript-Frameworks bieten einige Funktionen für die Behandlung dieses genauen Problems. Mit Prototype.js (zum Beispiel) Sie können dies tun:

this.doSomething(function() { this.doSomethingElse(); }.bind(this)); 

Ihre "Hack" jedoch in Ordnung ist. Normalerweise mache ich eine (function (self) { ... })(this) um alle Funktionen, die ich brauche eine lexikalisch begrenzte this-ähnliche Variable.

1

Es ist auch erwähnenswert, dass die nächste Version von ECMAScript (die Sprachspezifikation für JavaScript) Function.bind() einführt, mit der Sie einen permanenten Kontext für eine Funktion angeben können.