Maison >interface Web >js tutoriel >Implémentation des méthodes Ruby Méthode en JavaScript
Du coup, la méthode des méthodes de Ruby n'est-elle pas pratique ? Lors de l'écriture de code, il répertorie toutes les méthodes et propriétés disponibles pour un objet et vous permet de les parcourir, ce qui est très utile pour le débogage.
En plus de cela, il est également efficace pour vérifier les méthodes spécifiques aux frameworks comme Rails, aidant à la lecture du code et à la compréhension des bibliothèques. Bien qu'il soit recommandé de se référer à la documentation officielle ou au code source, la méthode des méthodes est très utile pour les bibliothèques où vous n'avez pas besoin de plonger en profondeur ou lorsque vous avez de vagues souvenirs des noms de méthodes.
Pour présenter brièvement la méthode des méthodes de Ruby, cela ressemble à ceci :
Objet#méthode
Renvoie une liste des noms des méthodes publiques et protégées d'obj. Cela inclura toutes les méthodes accessibles dans les ancêtres d’obj. Si le paramètre facultatif est faux, il renvoie un tableau de méthodes singleton publiques et protégées d'obj, le tableau n'inclura pas les méthodes des modules inclus dans obj.
En d'autres termes, il renvoie un objet tableau des propriétés et méthodes accessibles depuis le récepteur.
Cette méthode est implémentée dans la classe Object, qui est l'ancêtre de toutes les classes qui héritent d'Object, elle peut donc être utilisée dans n'importe quelle classe héritant d'Object.
Exemple de code
class Hoge attr_accessor :fuga def bar puts '' end end puts Hoge.new.methods // => [:bar, :fuga=, :fuga, :hash, :singleton_class, :dup, ...] puts Hoge.new.grep /fuga/ // => [:fuga=, :fuga]
Comme le montre l'exemple, il renvoie un objet Array, vous pouvez donc également effectuer une recherche dans la liste des méthodes en utilisant la méthode grep, ce qui est très pratique.
Alors, j'ai réfléchi à la question de savoir si cela pouvait être fait en JS et j'ai essayé.
Vous trouverez ci-dessous le code réel.
Le nom de la classe peut être n'importe quoi, mais je l'appelle PropertyFinder pour l'instant.
class PropertyFinder { constructor(receiver) { this.receiver = receiver } grep(regexp, options = {}) { let res = [] if (typeof regexp === 'string') { return this.find((name) => name.includes(regexp)) } if (regexp instanceof RegExp) { return this.find((name) => regexp.test(name)) } return [] } toString() { return this.find(() => true) } find(detect) { const list = Object.getOwnPropertyNames(this.receiver).filter(it => detect(it)) if (!this.receiver.__proto__) { return list } const ancestors = new PropertyFinder(this.receiver.__proto__).find(detect) return [...list, ...ancestors] } }
J'expliquerai le code plus tard, mais commençons par comment l'utiliser.
Une fois la classe définie, vous pouvez ajouter une méthode aux propriétés de la classe Object comme suit :
Object.prototype.methods = function () { return new PropertyFinder(this) }
En faisant cela, vous pouvez utiliser la méthode méthodes sur des instances de classes héritant d'Object. Cependant, veuillez prendre note de la mise en garde ci-dessous et utilisez-la à vos propres risques.
Voici quelques exemples d'exécutions :
class Hoge { fuga() { console.log('fuga') } } console.log(new Object().methods().toString()) // => ['constructor', 'constructor', '__defineGetter__', '__defineSetter__', 'hasOwnProperty' ...] console.log([].methods().toString()) // => ['length', 'length', 'constructor', 'at', 'concat', ...] console.log(new Hoge().methods().grep(/fuga/) // => ['fuga']
*Ce code n'est pas recommandé pour une utilisation dans les environnements de production *
L'ajout de propriétés à des classes de niveau supérieur via le patch singe est un anti-modèle et pourrait entraîner des problèmes avec les modifications futures des spécifications JS. Utilisez-le avec prudence et à vos propres risques.
Référence : Les inconvénients du patching singe
Maintenant, passons à l'explication du code.
La méthode la plus importante dans PropertyFinder est la méthode find. Cette méthode parcourt la chaîne de prototypes de l'objet donné, recherche les propriétés accessibles et les renvoie sous forme de liste.
Les méthodes toString et grep utilisent simplement find, elles n'ont donc pas besoin d'explications supplémentaires.
La chaîne de prototypes n'est peut-être pas familière à certains, mais il s'agit de l'héritage des propriétés de la classe Object.
L'héritage et la chaîne des prototypes | MDN
Les détails sont traités dans la documentation MDN, mais le mécanisme d'héritage de JavaScript est pris en charge par la chaîne de prototypes.
Bien que ce ne soit pas toujours évident, lorsqu'on fait référence à une propriété, le processus implique :
Ce processus continue tout au long de la chaîne jusqu'à ce qu'une correspondance soit trouvée, qui est ensuite renvoyée.
Compte tenu de ce qui précède, la méthode find de PropertyFinder implémente ce mécanisme, vous permettant d'obtenir une liste de propriétés en explorant récursivement __proto__.
Voici l'implémentation qui permet d'atteindre cet objectif en explorant __proto__ de manière récursive pour obtenir la liste :
find(detect) { const list = Object.getOwnPropertyNames(this.receiver).filter(it => detect(it)) if (!this.receiver.__proto__) { return list } const ancestors = new PropertyFinder(this.receiver.__proto__).find(detect) return [...list, ...ancestors] }
Cela conclut l'explication de PropertyFinder.
Cela conclut l'explication du code et ce que j'ai essayé.
Il s'agissait plutôt d'un exercice expérimental ou ludique, mais comme il impliquait quelques connaissances et techniques, j'espère que vous le trouverez utile ou inspirant pour vos propres applications.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!