Maison  >  Article  >  interface Web  >  Implémentation des méthodes Ruby Méthode en JavaScript

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

WBOY
WBOYoriginal
2024-07-31 06:30:13969parcourir

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

Méthodes de Ruby Méthode

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

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

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.

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 :

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

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 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn