„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Implementieren der Methoden von Ruby in JavaScript

Implementieren der Methoden von Ruby in JavaScript

Veröffentlicht am 21.08.2024
Durchsuche:115

Implementing Ruby

Ist Rubys Methodenmethode nicht plötzlich praktisch? Beim Schreiben von Code werden alle für ein Objekt verfügbaren Methoden und Eigenschaften aufgelistet und Sie können diese durchsuchen, was beim Debuggen sehr nützlich ist.

Darüber hinaus ist es auch effektiv für die Überprüfung von Methoden, die für Frameworks wie Rails spezifisch sind, und hilft beim Lesen von Code und beim Verstehen von Bibliotheken. Während es eine gute Praxis ist, sich auf die offizielle Dokumentation oder den Quellcode zu beziehen, ist die Methodenmethode sehr hilfreich für Bibliotheken, in denen Sie nicht tief eintauchen müssen oder wenn Sie vage Erinnerungen an Methodennamen haben.

Rubys Methoden Methode

Um Rubys Methodenmethode kurz vorzustellen, sieht sie so aus:

Objekt#Methode

Gibt eine Liste der Namen öffentlicher und geschützter Methoden von obj zurück. Dies umfasst alle Methoden, auf die in den Vorgängern von obj zugegriffen werden kann. Wenn der optionale Parameter „false“ ist, wird ein Array der öffentlichen und geschützten Singleton-Methoden von obj zurückgegeben. Das Array enthält keine Methoden in Modulen, die in obj enthalten sind.

Mit anderen Worten: Es wird ein Array-Objekt der Eigenschaften und Methoden zurückgegeben, auf die vom Empfänger aus zugegriffen werden kann.

Diese Methode ist in der Object-Klasse implementiert, die der Vorfahre aller Klassen ist, die von Object erben, sodass sie in jeder Klasse verwendet werden kann, die von Object erbt.

Beispielcode

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]

Wie im Beispiel gezeigt, gibt es ein Array-Objekt zurück, sodass Sie die Liste der Methoden auch mit der grep-Methode durchsuchen können, was sehr praktisch ist.

Also habe ich darüber nachgedacht, ob dies in JS möglich ist, und habe es ausprobiert.

Durchführung

Unten ist der eigentliche Code.

Der Klassenname kann beliebig sein, aber ich nenne ihn vorerst PropertyFinder.

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

Ich werde den Code später erklären, aber beginnen wir mit der Verwendung.

Sobald die Klasse definiert ist, können Sie den Eigenschaften der Objektklasse wie folgt eine Methode hinzufügen:

Object.prototype.methods = function () {
    return new PropertyFinder(this)
}

Auf diese Weise können Sie die Methodenmethode für Instanzen von Klassen verwenden, die von Object erben. Bitte beachten Sie jedoch den folgenden Warnhinweis und verwenden Sie ihn auf eigenes Risiko.

Hier einige Beispielausführungen:

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

Sicherheitseinführung

*Dieser Code wird nicht für die Verwendung in Produktionsumgebungen empfohlen *

Das Hinzufügen von Eigenschaften zu höheren Klassen durch Monkey-Patching ist ein Anti-Pattern und könnte zu Problemen bei zukünftigen Änderungen in JS-Spezifikationen führen. Verwenden Sie es mit Vorsicht und auf eigenes Risiko.

Referenz: Die Nachteile von Monkey Patching

Code-Erklärung

Lassen Sie uns nun mit der Erklärung des Codes fortfahren.

Die wichtigste Methode im PropertyFinder ist die Find-Methode. Diese Methode durchläuft die Prototypenkette des angegebenen Objekts, sucht nach zugänglichen Eigenschaften und gibt sie als Liste zurück.

Die Methoden toString und grep verwenden einfach find, sodass sie keiner weiteren Erklärung bedürfen.

Prototypenkette

Die Prototypenkette mag einigen unbekannt sein, aber es handelt sich um die Vererbung von Eigenschaften aus der Object-Klasse.

Vererbung und die Prototypenkette | MDN

Die Details werden in der MDN-Dokumentation behandelt, aber der Vererbungsmechanismus von JavaScript wird von der Prototypenkette unterstützt.

Obwohl es nicht immer offensichtlich ist, umfasst der Prozess bei der Bezugnahme auf eine Eigenschaft Folgendes:

  1. Prüfung, ob der Empfänger selbst über die Eigenschaft verfügt.
  2. Überprüfen, ob die übergeordnete Klasseninstanz über die Eigenschaft verfügt.
  3. Überprüfen, ob die Eigenschaft in der übergeordneten Klasse der Instanz der übergeordneten Klasse vorhanden ist.

Dieser Prozess wird in der Kette fortgesetzt, bis eine Übereinstimmung gefunden wird, die dann zurückgegeben wird.

Was die find-Methode bewirkt

Angesichts des oben Gesagten implementiert die Suchmethode in PropertyFinder diesen Mechanismus, sodass Sie durch rekursives Durchsuchen von __proto__ eine Liste von Eigenschaften erhalten können.

Hier ist die Implementierung, die dies erreicht, indem sie __proto__ rekursiv durchsucht, um die Liste zu erhalten:

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

Damit ist die Erklärung von PropertyFinder abgeschlossen.

Einpacken

Das schließt die Erklärung des Codes und meiner Versuche ab.

Dies war eher eine experimentelle oder spielerische Übung, aber da sie einige Kenntnisse und Techniken beinhaltete, hoffe ich, dass Sie sie für Ihre eigenen Anwendungen nützlich oder inspirierend finden.

Freigabeerklärung Dieser Artikel ist abgedruckt unter: https://dev.to/version1/implementing-rubys-methods-method-in-javascript-p1e?1 Bei Verstößen wenden Sie sich bitte an [email protected], um ihn zu löschen
Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3