2009-12-17 5 views
4

J'essaie d'écrire une méthode d'aide en JavaScript. Il devrait agir différemment si l'on envoie une fonction ou une référence à une fonction.Savoir si la fonction est anonyme ou est définie dans un objet

Je veux vous l'utiliser comme ceci:

helper('div', function() { return false; }) 
helper('div', obj.fn) 

Ce que je ne peux pas comprendre est la suivante: comment l'intérieur de la fonction d'aide faire la différence entre les deux?

Je pense qu'il est dû à cette JavaScript évalue d'abord la obj.fn avant qu'elle ne l'envoie dans. La seule solution que j'ai trouvé est d'envoyer le obj.fn comme obj, à savoir

helper('div', { fn: obj.fn }) 

Je peut faire la différence entre les deux avec typeof. Mais j'aime vraiment un moyen de le faire sans la déclaration d'objet supplémentaire.

+2

Avez-vous une raison particulière pour laquelle vous voulez distinguer deux fonctions? – Boldewyn

+3

"Il faut agir différemment si l'on envoie une fonction ou une référence à une fonction" - qu'est-ce que cela signifie?Comment définissez-vous la différence entre une "fonction" et une "référence à une fonction"? Dans votre premier exemple, le paramètre passé à helper sera une référence à une fonction dans les deux sens. –

+0

@Tim Down, qui m'a aussi troublé mais je pense que le demandeur suppose que le passage d'une fonction anonyme passe par valeur-value et que passer une méthode objet passe par-référence qui est faux bien sûr mais c'est une erreur de nombreux développeurs. –

Répondre

0

Vous pouvez utiliser toString() pour savoir si la fonction est anonyme en supposant qu'elle est déclarée comme une fonction nommée et non une fonction sans nom attribué à une variable:

function jim() { var h = "hello"; } 
function jeff(func) 
{ 
    var fName; 
    var inFunc = func.toString(); 
    var rExp = /^function ([^\s]+) \(\)/; 
    if (fName = inFunc.match(rExp)) 
     fName = fName[1]; 

    alert(fName); 
} 

vous donnera la nom de la fonction le cas échéant.

jeff(function() { blah(); }); // alert: null; 
jeff(function joe() { blah(); }); // alert: "joe"; 
jeff(jack); // "jack" if jack is function jack() { }, null if jack = function() {} 

Ma précédente édition fait référence à une bizarrerie IE qui n'existait pas dans d'autres navigateurs et n'est plus valide dans IE de la version 9. Toutefois, vous pouvez affecter encore des fonctions nommées comme propriétés de l'objet en utilisant une fonction nommée expression:

var obj = { 
    fn: function namedFunction() { } 
}; 

cela fonctionne dans tous les navigateurs, mais IE 8 et inférieure ne respectent pas la spécification qui dit que la fonction est disponible uniquement par ce nom dans son propre bloc.

+0

Je pensais que 'jack = function() {}' était le même que 'function jack() {}', ou peut-être que je me suis mélangé avec Scheme ... – Skilldrick

+0

'function jack() {}' est une fonction nommée, 'jack = function() {}' est une fonction sans nom assignée à une variable. –

+0

J'aimerais savoir ce que le -1 était pour ... –

2

MISE À JOUR * (ENCORE): Je pensais que la méthode toString() pourrait être votre seul moyen d'avancer ici. Il ne traite cependant pas différemment une référence d'un objet anonyme.

Ce code démontre que:

function acceptparam(fn){ 

      console.log("fn.constructor = " + fn.constructor); 
      console.log("typeof fn = " + typeof fn); 
      console.log("fn toString " + fn.toString()); 

      console.log("fn.prototype = " + fn.prototype); 
      console.log("fn.prototype.constructor = " + fn.prototype.constructor); 
      console.log("this[0] = " + this[0]); 
      console.log("---"); 

     } 

     function empty(){ 
      return ; 
     } 

     var x = { 
      y : function(){return;} 
     } 

     acceptparam(empty); 
     acceptparam(function(){return;}); 
     acceptparam(x.y); 

question très intéressante, sans mettre en œuvre votre propre solution, je ne pense pas que vous pouvez le faire, ce poste aide à expliquer pourquoi. C'est à propos de la relation parent-enfant que d'être à sens unique.

http://codingforums.com/showthread.php?t=134855

+0

Vous aviez raison sur toString ... regardez attentivement la sortie de la console: 'fn toString fonction vide()' vs 'fn toString fonction()' – Skilldrick

+0

Qu'est-ce que la réponse d'Andy E fait: P – Skilldrick

+3

Ce n'est pas ce qu'il demande pour thoguh, qui est où je me suis trompé à l'origine! fredrik demande la différence entre une fonction anonyme et un objet avec une fonction enfant, ce qui ne marche pas. – Lewis

1

Je pensais que j'ajouterais une autre réponse alternative, principalement parce que je ne voulais pas ajouter à la soupe qui est mon autre réponse, mais aussi parce que cela ne s'est pas bien passé avec les électeurs de stackoverflow qui ne le font pas laisser ;-)

commentaires constructifs comme alternative à ce que vous essayez de faire, vous pouvez ajouter un troisième paramètre à la fonction d'aide:

function helper (tagName, fn, method) 
{ 
    if (method) 
     fn = fn[method]; 

    //- Do rest of helper function here 
} 
//- Now if we pass an object method to helper function we can identify it properly 
helper('div', obj, "fn"); // method is obj.fn 
helper('div', function() { blah(); }); // Still works fine 

le simple fait une suggestion et fonctionne aussi bien ou même mieux que votre travail actuel.

+0

Merci. Mais en fait c'est ma première chose que j'ai essayé. Mais je voulais le rendre aussi simple que possible. Mais en train de jouer avec ça pendant un moment maintenant. Et il semble que je dois spécifier l'obj qui détient la fonction en raison de ce que je veux, puis le fn est déclenché, il devrait être dans le bon scoop. Alors que le mot-clé this est référé à obj. – fredrik

Questions connexes