2010-09-17 7 views
1

Je ne sais pas ce que je fais mal ici, je veux juste être en mesure d'avoir des fonctions d'un objet de référence du champ d'objetJavaScript - Invoquer méthodes qui font référence à ce

myscipt.js

function MyFoo() { 
    this.name = 'myname'; 
} 

function MyBar() { 
    this.myFoo = new MyFoo(); 

    function setMyFoosName(name) { 
     this.myFoo.name = name; 
    } 
} 

somepage.html

<scipt> 

$('document').ready(function() { 
    $.myBar = new MyBar(); 
} 

... 
some action 
... 

$.myBar.setMyFoosName('new name'); 

</script> 

cela jette une exception:

this.myFoo.name = name; this.myFoo is not defined 

Répondre

4

Lekensteyn et Ken ont droit à moitié chacun.

  1. Vous devez mettre "this" dans une variable, comme Lekensteyn l'a fait, afin de pouvoir également le référencer à l'intérieur de la fonction imbriquée.
  2. Vous devez rendre setMyFoosName accessible en dehors de la portée de MyBar, en l'affectant à une propriété de "this", comme Ken l'a fait.

Voilà comment je le ferais:

function MyFoo() { 
    this.name = 'myname'; 
} 

function MyBar() { 
    var that = this; 
    this.myFoo = new MyFoo(); 

    this.setMyFoosName = function(name) { 
     that.myFoo.name = name; 
    } 
} 
+0

Si 'myFoo' ne doit stocker qu'une référence à' MyFoo', il est préférable de le rendre privé. Vois ma réponse. – Lekensteyn

+0

En fait, @Ken aussi bien, j'étais sur le point de commenter dans sa réponse, mais il a été supprimé.Tout dépend de la façon dont vous appelez la fonction 'setMyFoosName', puisqu'il s'agit d'une" méthode d'instance ", vous n'avez pas vraiment besoin de la variable' that', car la méthode s'appelle 'myBarInstance.setMyFoosName ('foo') ', et la valeur' this' à l'intérieur de la méthode se référera à l'objet de base * de la référence où il a été appelé. Cochez [cet exemple] (http://jsbin.com/uyuti3/edit) sans 'that'. – CMS

+0

CMS: Observation intéressante. Il n'y a qu'une différence délicate (cela apparaîtra si l'on commence à jongler avec les méthodes), mais cela n'a probablement pas d'importance en pratique. Je vais préciser si quelqu'un est intéressé, mais il suffira probablement de dire que mon approche et celle qui a été supprimée par Ken fonctionneront dans ce cas. Merci CMS! – Jakob

0

this fait référence à la portée de setMyFoosName. Vous devriez mettre this dans une variable, et se référer à cette variable:

function MyFoo() { 
    this.name = 'myname'; 
} 

function MyBar() { 
    var that = this; 
    this.myFoo = new MyFoo(); 

    this.setMyFoosName = function(name) { 
     that.myFoo.name = name; 
    } 
} 

Essayez d'éviter les variables d'exportation qui devrait rester privé:

function myFoo() { 
    this.name = 'myname'; 
} 

function MyBar() { 
    /* myFoo is private */ 
    var myFoo = new MyFoo(); 
    this.setMyFoosName = function(name) { 
     myFoo.name = name; 
    } 
} 

De cette façon, vous ne pouvez pas briser votre fonction avec:

$.myBar = new MyBar(); 
$.myBar.myFoo = new EvilObject(); 
$.myBar.setMyFoosName(); 

Bien sûr, cela dépend de votre utilisation, si myFoo devrait être remplaçable ou non.

+1

Voir aussi: Closures en JavaScript (http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures /) – annakata

+1

-1. Cela ne marchera pas. setMyFoosName ne sera pas accessible en dehors de la fonction MyBar. – Jakob

+0

Cependant, je dois souligner que le conseil général (mettre "ceci" dans une variable et l'utiliser à la place) est la bonne façon de procéder. Jetez un oeil à ma version. – Jakob

0

Vous ne pouvez pas faire une méthode statique d'instance avec le type de données JSON? Donne une portée plus globale, et ainsi de suite, tant que MyFoo est dans la portée globale.

Example here.

Questions connexes