2013-07-15 1 views
3

Je veux remplacer js arguments.callee par un autre symbole comme SELF.Récursivité anonyme - un moyen de remplacer javascript 'arguments.callee' par un autre symol tel que 'SELF'?

Est-ce possible?

Une approche macro telle que sweetjs est le seul moyen?


EDIT

Merci beaucoup pour les entrées:

Je comprends arguments.callee est interdite dans StrictMode.

Pour rendre les choses claires, je vous présente mon code: récursion anonyme

var factorial = function (n) 
{ 
    return n ? n * arguments.callee(n - 1) : 1; 
}; 
console.log(factorial(10)); //3628800 

et maintenant

var SELF = function (val) 
{ 
    return arguments.callee(val); 
} 
var factorial = function (n) 
{ 
    return n ? n * SELF(n - 1) : 1; 
}; 
console.log(factorial(10)); 

donne une erreur

var SELF = function (val) 
        ^
RangeError: Maximum call stack size exceeded 

De plus, je sais qu'il ya manière pour récursivité anonyme pour ne pas utiliser arguments.callee, mais pour utiliser Y-Combinator.

Mais, arguments.callee ne peut pas être remplacé par une telle chose? Dans Y-Combinator Scénario, le code doit être

var f = function(f) { 
      return function(n){ 
       return n ? n * f(n - 1) : 1; 
      } 
     } 

Le nid devient plus profond pour définir factoriel, etc. que je ne suis pas prêt à ...


EDIT2

après un court laps de temps, un bon article frappe.

Anonymous recursion in 6 lines of Javascript

L'auteur Arne Martin appelle z-Combinator:

var Z = function(func) 
{ 
    var f = function() 
    { 
     return func.apply(null, [f].concat([].slice.apply(arguments))); 
    }; 
    return f; 
} 

var factorial = function (f, n) 
{ 
    return n ? n * f(n - 1) : 1; 
} 

console.log( Z(factorial)(10)); 

Cette méthode remplit parfaitement mes besoins, et aussi car il ne nécessite pas 'arguments.callee', nous don Ne vous inquiétez pas du mode strict!

+0

Vous pouvez utiliser une expression de fonction nommée et utiliser ce nom à l'intérieur. – elclanrs

+0

Ne pourriez-vous pas simplement utiliser 'var SELF = arguments.callee;' ou est-ce que quelque chose me manque? – Shawn31313

+1

Juste un heads-up: l'utilisation de 'arguments.callee' lancera un' TypeError' en mode strict. – founddrama

Répondre

3

si vous ne voulez pas utiliser le mode strict et ne me dérange pas utiliser des variables globales et les fonctionnalités dépréciées, vous pouvez ajouter en lecture seule commande « mots-clés » pour la plupart des implémentations JS modernes:

Object.defineProperty(
self, 
"SELF", 
{get:function(){return arguments.callee.caller;} //!! deprecated feature in use!! 
}); 


function demo(a,b){ 
    alert(SELF); 
} 

function someOtherFunction(a,b){ 
    alert(SELF); 
} 



demo(); 
someOtherFunction(); 

cette est cool et tout, mais il existe des moyens plus robustes et modernes de le faire, à savoir en utilisant le nom de la fonction:

function someAdditionalFunction(a,b){ 
    alert(someAdditionalFunction); 
} 

en utilisant le nom vous permet de saisir les mêmes informations que la « AUTO » getter ci-dessus, et travaille à mode strict et sans variables globales. Le seul inconvénient à utiliser les noms de fonction est que vous ne pouvez pas réutiliser le même symbole sur et plus, sauf si vous utilisez des expressions de fonction exclusivement nommées, et donner à vos fonctions et nom interne de l'auto:

var demo=function SELF(a,b){ 
    alert(SELF); 
}; 

var someOtherFunction=function SELF(a,b){ 
    alert(SELF); 
}; 

demo(); 
someOtherFunction(); 
+1

Soyez très prudent avec les expressions de fonction nommées - IE les rend globales. – RobG

+0

Attendez, pour de vrai? Même aujourd'hui? – ehdv

+0

Une recherche rapide indique au moins IE8. Aucune idée sur IE9 +. – Havvy

1

C'est ce que j'ai fait dans le passé pour une auto-référence des fonctions où je ne veux pas utiliser arguments.callee. Ajoutez simplement un nom dans la définition de la fonction:

var factorial = function factorialcallee(n) 
{ 
    return n ? n * factorialcallee(n - 1) : 1; 
}; 
console.log(factorial(10)); //3628800 
Questions connexes