"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Implémentation des méthodes Ruby Méthode en JavaScript

Implémentation des méthodes Ruby Méthode en JavaScript

Publié le 2024-08-21
Parcourir:681

Implementing Ruby

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 rechercher, 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, facilitant 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.

Méthodes de Ruby Méthode

Pour présenter brièvement la méthode des méthodes de Ruby, cela ressemble à ceci :

Méthode#Objet

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é.

Mise en œuvre

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 tenir compte 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']

Introduction à la sécurité

*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

Explication du code

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.

Chaîne prototype

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.

Héritage et chaîne de 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 :

  1. Vérifier si le destinataire lui-même possède la propriété.
  2. Vérifier si l'instance de classe parent possède la propriété.
  3. Vérifier si la propriété existe dans la classe parent de l'instance de la classe parent.

Ce processus continue tout au long de la chaîne jusqu'à ce qu'une correspondance soit trouvée, qui est ensuite renvoyée.

Ce que fait la méthode find

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 de manière récursive __proto__.

Voici l'implémentation qui permet d'y parvenir 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.

Conclure

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 des connaissances et des techniques, j'espère que vous le trouverez utile ou inspirant pour vos propres applications.

Déclaration de sortie Cet article est reproduit sur : https://dev.to/version1/implementing-rubys-methods-method-in-javascript-p1e?1 En cas de violation, veuillez contacter [email protected] pour le supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3