2010-09-10 4 views
2

Je vais commencer par un exemple extrait:Portée dans un objet littéral

self.addwidget({ 
    box: ns.box({       
       text:  'Foobar', 
       fromTop: ~~(Math.random()*window.innerHeight), 
       fromLeft: ~~(Math.random()*window.innerWidth), 
       toTop:  240, 
       toLeft:  40, 
       css:  'foobar', 
       easing:  'easeOutCirc', 
       duration: 2000, 
       events:  { 
        mousedown:  function(e){ 
         e.target.position = {x: e.pageX, y: e.pageY}; 
        }, 
        mouseup:  function(e){ 
         // "this" should reference be "box"          
        } 
       } 
    }), 
    delay: 3000 
}); 

Description succincte:
ns.box() prend un objet comme argument et crée une nouvelle jQuery object. Il utilise jQuery.extend() pour fusionner l'objet de propriété events avec le jQuery constructor $('<elem/>', {});
Après cela, ns.box() renvoie un nouvel objet qui contient certaines méthodes.
-

Ce que je veux archieve est d'avoir accès à ceux propertys/methods dans le event handlers. Bien sûr, je ne peux pas accéder à box.somemethod à ce stade parce que je ne peux pas référencer la propriété box externe à ce stade. J'ai donc essayé de changer la portée des gestionnaires d'événements avec jQuery.proxy(), à this, mais sans succès.
this.somemethod est non référencé, même si mandaté. J'ai également essayé de remplacer tous les objets par le haut -> vers le bas, sans succès non plus.

Est-il même possible dans une construction comme celle-ci, d'accéder aux propriétés à partir de l'objet retourné de ns.box(), dans les gestionnaires d'événements?

+2

Faut-il vraiment utiliser le '~~'? Parce que je suis à peu près sûr que quelqu'un viendra et demandera ce que cela veut dire. :) (http://james.padolsey.com/javascript/double-bitwise-not/ si vous êtes l'un d'entre eux) –

+0

@Yi: Je suis désolé, c'est juste une décharge de mon code. Je ne voulais pas confondre qui que ce soit ici. Votre lien devrait clarifier cela, merci. – jAndy

+0

@Yi Jiang: Bon lien, merci. J'aime son affirmation selon laquelle «c'est plus rapide». Il est presque impossible de faire de telles déclarations avec JavaScript, avec la variété des implémentations dans la nature. Ce qui est plus rapide sur IE n'est pas toujours plus rapide sur FF, etc. –

Répondre

4

Vous pouvez y parvenir avec une fonction de détermination de la portée, comme ceci:

self.addwidget((function() { 
    var box = ns.box({       
       text:  'Foobar', 
       fromTop: ~~(Math.random()*window.innerHeight), 
       fromLeft: ~~(Math.random()*window.innerWidth), 
       toTop:  240, 
       toLeft:  40, 
       css:  'foobar', 
       easing:  'easeOutCirc', 
       duration: 2000, 
       events:  { 
        mousedown:  function(e){ 
         e.target.position = {x: e.pageX, y: e.pageY}; 
        }, 
        mouseup:  function(e){ 
         // You can access `box` here       
        } 
       } 
    }); 

    return { 
     box: box, 
     delay: 3000 
    }; 
})()); 

En attribuant la boîte à une var dans notre fonction de cadrage, nous créons un symbole que les gestionnaires d'événements (qui sont closures) ferment plus et ont donc accès à. Nous appelons la fonction immédiatement, l'obligeant à retourner l'objet. Les références tenues par les fermetures sont durables, et donc ...

J'utilise ce modèle tout le temps parce que je n'aime pas avoir des fonctions anonymes (vos gestionnaires d'événements sont anonymes, par exemple); more here. Si je faisais ce qui précède, je ferais ceux qui sont nommés à la place, comme ceci:

self.addwidget((function() { 
    var box = ns.box({       
       text:  'Foobar', 
       fromTop: ~~(Math.random()*window.innerHeight), 
       fromLeft: ~~(Math.random()*window.innerWidth), 
       toTop:  240, 
       toLeft:  40, 
       css:  'foobar', 
       easing:  'easeOutCirc', 
       duration: 2000, 
       events:  { 
        mousedown:  boxMousedown, 
        mouseup:  boxMouseup 
       } 
    }); 

    function boxMousedown(e){ 
     e.target.position = {x: e.pageX, y: e.pageY}; 
    } 

    function boxMouseup(e){ 
     // You can access `box` here       
    } 

    return { 
     box: box, 
     delay: 3000 
    }; 
})()); 

Ces fonctions ont maintenant des noms qui peuvent apparaître dans les piles d'appels et des messages d'erreur, mais ils sont complètement privé, pas encombrer l'espace de noms global.

+0

En effet, belle suggestion T.J. En utilisant une fermeture de 'box', j'aurais dû m'en douter. – jAndy

+0

@ T.J. Crowder: que fait ~ ~() 'faire? – Robusto

+0

@Robusto: Voir le lien dans le commentaire de Yi Jiang sur la question. Je ne savais pas non plus avant de le lire. :-) –

Questions connexes