如何在JS(原型继承)中获取所有祖先的方法?



我需要在JS中创建一个函数,从整个继承树中获取所有方法,以便为每个方法插入一个<button>。我有这个代码

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();

我需要一些方法来找到整棵树的方法,以防我不知道一个对象有多少祖先。例如:如果一个对象C有A和B作为它的祖先,我需要来自A、B和C的方法;如果一个D对象是a-B-C的子对象,我需要它们四个(a、B、C和D)的方法。我可能能够手动跟踪每个方法,以便为我编写一个代码,购买我需要它是动态的。

这就是我正在使用的:

console.log(Object.getOwnPropertyNames(dd.__proto__).filter(function (property) {
return (
typeof dd.__proto__[property] === 'function' && property !== 'constructor'
);
}))

您的设置代码中有一个错误:

更改:

D.prototype = C;

至:

D.prototype = new C;

然后,要获得方法列表(即使不可枚举),请进行递归调用。你甚至可以把它做成发电机。

为了明确这些方法的来源,我在它们前面加了原型对象的名称(比如A.prototype)。您将看到,当具有相同名称的函数存在于原型链的多个级别时,它们会分别列出:

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))));

使用class ... extends语法时,更容易设置此原型层次结构。我也不会定义super,因为它是一个本机可用的关键字。以下是它的样子:

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))));

最新更新