JS(原型继承)中如何获取所有祖先的方法?
How can I get all the ancestors' methods in JS (prototypal inheritance)?
我需要在 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))));
我需要在 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))));