Necesito crear una función en JS que obtenga todos los métodos de todo el árbol de herencia para insertar un <button> para cada método. tengo este codigo
function A () { } A.prototype.a = function () { console.log('a'); } function B () { this.super = A; this.super(); } B.prototype = new A; B.prototype.constructor = B; B.prototype.b = function () { console.log('b'); } function C () { this.super = B; this.super(); } C.prototype = new B; C.prototype.constructor = C; C.prototype.c = function () { console.log('c'); } function D () { } D.prototype = C; D.prototype.constructor = D; D.prototype.d = function () { console.log('d'); } const dd = new D();Necesito alguna forma de encontrar los métodos de todo el árbol en caso de que no sepa cuántos ancestros tiene un objeto. Por ejemplo: si un objeto C tiene a A y B como ancestros, necesito los métodos de A, B y C; Si un objeto D fuera un hijo de ABC, necesito los métodos de los cuatro (A, B, C y D). Es posible que pueda rastrear a mano cada método para escribir un código que haga eso por mí, pero necesito que sea dinámico.
Esto es lo que estoy usando:
console.log(Object.getOwnPropertyNames(dd.__proto__).filter(function (property) { return ( typeof dd.__proto__[property] === 'function' && property !== 'constructor' ); }))Hay un error en su código de configuración:
Cambio:
D.prototype = C;a:
D.prototype = new C;Luego, para obtener la lista de métodos (incluso cuando no se pueden enumerar), realice una llamada recursiva. Incluso puedes convertirlo en un generador.
Para aclarar de dónde provienen los métodos, les prefijé el nombre del objeto prototipo (como A.prototype ). Verá que cuando existen funciones con el mismo nombre en varios niveles de la cadena de prototipos, cada una aparece en la lista:
function * iterMethods(o) { if (!o || o === Object.prototype) return; for (let name of Object.getOwnPropertyNames(o)) { try { if (name !== "constructor" && typeof o[name] === "function") { yield o.constructor.name + ".prototype." + name; } } catch {} } yield * iterMethods(Object.getPrototypeOf(o)); } // Your code: function A () { } A.prototype.a = function () { console.log('a'); } function B () { this.super = A; this.super(); } B.prototype = new A; B.prototype.constructor = B; B.prototype.b = function () { console.log('b'); } function C () { this.super = B; this.super(); } C.prototype = new B; C.prototype.constructor = C; C.prototype.c = function () { console.log('c'); } function D () { } D.prototype = new C; D.prototype.constructor = D; D.prototype.d = function () { console.log('d'); } const dd = new D(); // The call: console.log(Array.from(iterMethods(Object.getPrototypeOf(dd)))); Es más fácil configurar esta jerarquía prototípica cuando usa la sintaxis class ... extends . Tampoco definiría super ya que es una palabra clave que está disponible de forma nativa. Así es como se vería:
function * iterMethods(o) { if (!o || o === Object.prototype) return; for (let name of Object.getOwnPropertyNames(o)) { try { if (name !== "constructor" && typeof o[name] === "function") { yield o.constructor.name + ".prototype." + name; } } catch {} } yield * iterMethods(Object.getPrototypeOf(o)); } // class syntax version: class A { a() { console.log('a'); } } class B extends A { b() { console.log('b'); } } class C extends B { c() { console.log('c'); } } class D extends C { d() { console.log('d'); } } const dd = new D(); // The call: console.log(Array.from(iterMethods(Object.getPrototypeOf(dd))));