2010-02-12 7 views
7

J'ai une classe JavaScript qui ressemble à ceci:Portée de « ce » en JavaScript

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

    this.doSomethingElse = function() 
    { 

    } 
} 

Ce code renvoie une erreur parce que la portée de cette « » à l'intérieur de la fonction qui est passé dans doSomething() est différent de celui de "ceci" en dehors de cette fonction.

Je comprends pourquoi c'est, mais quelle est la meilleure façon de gérer cela? C'est ce que je finis par faire:

function SomeFunction() 
{ 
    var thisObject = this; 

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

    this.doSomethingElse = function() 
    { 

    } 
} 

Cela fonctionne très bien, mais cela ressemble à un hack. Je me demandais juste si quelqu'un avait un meilleur moyen.

+2

@Jon Kruger C'est aussi ce que je fais. Je pense que c'est plutôt normal. Vous pouvez changer 'this' avec' call' et 'apply', mais cela ne correspond pas toujours à ce que vous faites bien. Une autre option est de passer 'this' en paramètre, mais cela ressemble plus à un hack. –

+0

@Jonathon Que voulez-vous dire par "Vous pouvez changer cela avec appel et appliquer"? –

+1

@Jon Kruger Voir aussi, consultez leur article pour 'call', aussi: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply –

Répondre

10

C'est la solution de contournement correcte et généralement acceptée. C'est une sorte de kludgy mais c'est ce que tout le monde fait. En général, cette variable supplémentaire est nommé self, comme dans:

function SomeFunction() 
{ 
    var self = this; 

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

    this.doSomethingElse = function() 
    { 

    } 
} 
+1

Sachez que 'self' est une propriété de l'objet window dans les navigateurs qui pointe sur lui-même, bien que cela ne cause aucun problème. –

+0

D'autres noms que j'ai vu utilisés un peu sont 'that' et' me', selon le contexte. – cHao

3

this à une dynamique "portée". Cela signifie qu'il est mis en place par tout ce qui le lie, et this est lié par un "appel de méthode". Autrement dit, tout moment dans votre programme, vous voyez ceci: w.f() puis en f est exécuté, this est dynamiquement lié à f, même sif avait this dans son champ lexical.

La plupart des frameworks JavaScript offrent des fonctionnalités permettant de résoudre ce problème. Avec Prototype.js (par exemple), vous pouvez le faire:

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

Votre "hack" est cependant très bien. Je fais généralement un (function (self) { ... })(this) autour de toutes les fonctions dont j'ai besoin d'une variable semblable à celle du this.

1

Il est également à noter que la prochaine version d'ECMAScript (la spécification de langage pour JavaScript) va introduire Function.bind(), ce qui vous permettra de spécifier un contexte permanent pour une fonction.