Se référer à la fonction javascript à partir d'elle-même

Considérez ce code

var crazy = function() { console.log(this); console.log(this.isCrazy); // wrong. } crazy.isCrazy = 'totally'; crazy(); // ouput => // DOMWindow // undefined 

De l'intérieur de crazy () 'this' se réfère à la fenêtre, ce qui me semble logique, car normalement vous voudriez que cela se réfère à l'objet auquel la fonction est associée, mais comment puis-je faire fonctionner la fonction et accéder Une propriété sur elle-même?

Répondre:

N'utilisez pas arguments.callee, utilisez simplement une fonction nommée.

"Remarque: Vous devez éviter d'utiliser arguments.callee () et de donner à chaque fonction (expression) un nom." Via l' article MDN sur arguments.callee

Je pense que vous demandez arguments.callee, mais il est obsolète maintenant.

https://developer.mozilla.org/fr/JavaScript/Reference/Functions_and_function_scope/arguments/callee

 var crazy = function() { console.log(this); console.log(arguments.callee.isCrazy); // right. } crazy.isCrazy = 'totally'; crazy(); // ouput => // DOMWindow // totally 

Comme l'a dit Rfw , c'est le moyen le plus simple à parcourir si la fonction a un seul nom:

 var crazy = function() { console.log(crazy); console.log(crazy.isCrazy); }; crazy.isCrazy = 'totally'; crazy(); 

Dans le cas où il peut avoir des noms différents, ou si vous vouliez le transmettre, il doit être enveloppé dans une fermeture:

 var crazy = (function(){ var that = function() { console.log(that); console.log(that.isCrazy); }; return that; })(); crazy.isCrazy = 'totally'; crazy(); 

Vous devez lui donner son propre nom, donc:

 var crazy = function() { console.log(crazy); console.log(crazy.isCrazy); } crazy.isCrazy = 'totally'; crazy(); 

La variable est seulement applicable dans la portée d'un objet, par exemple, si vous avez invoqué votre version de la fonction crazy avec crazy.call(crazy) , elle appellera la fonction dans le contexte de la fonction crazy et tout ira bien .

Cela doit faire face à la portée de la fonction crazy . Si vous pouvez transmettre toute portée à une fonction en utilisant l' call() fonction call() .

Au lieu de

 crazy(); 

Utilisation

 crazy.call(crazy); 

Pour plus de détails
http://odetocode.com/blogs/scott/archive/2007/07/05/function-apply-and-function-call-in-javascript.aspx
https://developer.mozilla.org/fr/JavaScript/Reference/Global_Objects/Function/Call
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5 -ways-to-call-a-function.aspx

Vous pouvez utiliser la méthode d' call

 var crazy = function() { console.log(this); console.log(this.isCrazy); } crazy.isCrazy = 'totally'; crazy.call(crazy); // calls crazy using crazy as the target, instead of window: // functionToCall.call(objectToUseForThis); 

Bien que si votre fonction n'a qu'un seul nom, vous pouvez le faire:

 var crazy = function() { console.log(crazy); console.log(crazy.isCrazy); } crazy.isCrazy = 'totally'; crazy(); 

Comment puis-je obtenir la fonction de se référer à elle-même?

L'idée de «lui-même» n'existe pas avec les fonctions. Ce dont vous avez besoin, c'est un objet et pas seulement une fonction. Un objet possède une connaissance de lui-même disponible via le mot-clé 'this'. Dans une fonction, 'this' indique l'objet global – dans ce cas l'objet fenêtre. Mais si vous utilisez votre fonction en tant que fonction constructeur pour créer un objet (à l'aide du nouvel opérateur), le pointeur 'this' de l'objet désignera l'objet lui-même.

C'est-à dire que cela indique l'objet si vous écrivez:

 var anObject = new crazy(); 

Vous pouvez donc réécrire votre code comme suit:

 var crazy = function() { this.printMe = function(){ console.log(this); console.log(this.isCrazy); } } var anObject = new crazy(); //create an object anObject.isCrazy = 'totally'; //add a new property to the object anObject.printMe(); //now print 

Dans le cas où vous souhaitez ajouter la propriété avant que l'objet ne soit créé, vous devez ajouter la propriété au prototype de la fonction comme suit:

 var crazy = function() { console.log(this); console.log(this.isCrazy); } crazy.prototype.isCrazy = 'totally'; //add the property to the function's prototype var anObject = new crazy(); //invoke the constructor 

Voir plus sur mon blog pour une explication détaillée de ces concepts avec des exemples de code.

Reliez la fonction à elle-même (en prenant un indice des réponses par @ArunPJohny et @BudgieInWA):

 crazy = crazy.bind(crazy); 

Cela vous donnera accès à partir de la fonction à ses propriétés via this .

 > crazy() function () { console.log(this); console.log(this.isCrazy); // works now } 

Cela semble être une meilleure solution que la réponse acceptée, qui utilise la fonction callee qui est obsolète et ne fonctionne pas en mode strict.

Vous pourriez également maintenant avoir la fonction appeler lui-même récursivement avec this() si vous étiez si enclin.

Nous allons appeler cela auto-renouvelable . Ecrivez une fonction d'utilité:

 function selfthisify(fn) { return fn.bind(fn); } crazy = selfthisify(crazy); crazy(); 

Ou, si vous préférez plus de noms "sémantiques", vous pouvez l'appeler accessOwnProps .

Si vous êtes un type de sucre syntaxique, vous pouvez ajouter une propriété selfthisify au prototype Fonction:

 Object.defineProperty(Function.prototype, 'selfthisify', { get: function() { return this.bind(this); } }); 

Maintenant, vous pouvez dire

 crazy.selfthisify(); 

Le moyen le plus simple de rendre la fonction elle-même disponible dans son corps est de faire var crazy = function crazy2() { crazy2(); } var crazy = function crazy2() { crazy2(); } , Il est bon pour crazy et crazy2 d'avoir le même nom depuis la première occurrence, c'est le nom dans le champ extérieur et le second est le nom dans le corps de la fonction.

Ou simplement function crazy() { crazy(); } function crazy() { crazy(); } Qui définira le fou dans les deux domaines.

Es-tu réellement essayer de créer un objet 'classe'?

 function crazy(crazyState) { this.isCrazy = crazyState; console.log(this); console.log(this.isCrazy); } crazy.prototype.alertMe = function() { alert('I am '+ this.isCrazy +' crazy.'); } var crazyObj = new crazy('totally'); crazyObj.alertMe(); crazyObj.isCrazy = 'not'; crazyObj.alertMe(); 

Plutôt drôle, demandez-moi. Je viens d'examiner ce même problème dans un but différent . La version rapide du code final est:

 $a = function() {}; $ = function() { if (!(this instanceof $)) { return new $(); } this.name = "levi"; return this; }; //helper function var log = function(message) { document.write((message ? message : '') + "<br/>"); }; log("$().name == window.name: " + ($().name == window.name)); //false log("$().name: " + $().name); //levi log("window.name: " + window.name); //result log(); log("$a instanceof $: " + ($a instanceof $)); //false log("typeof $a: " + (typeof $a)); //function log("typeof $: " + (typeof $)); //function 

La pièce critique:

  if (!(this instanceof $)) { return new $(); } 

Si this ne fait pas référence à un objet du type approprié, il en fait un new , qui sera correctement compris. Le reste du code est juste là pour vérifier qu'il fonctionne bien comme prévu.