Reputation: 5864
Is there a way to determine if a function is a method of a certain class?
I have a class A
with a method doesMethodBelongHere
, that takes a function as an argument method
. I want to determine that method
is an actual method of A
.
class A {
methodA() {
console.log('method of A');
}
doesMethodBelongHere(method) {
// it should return true if `method` argument is a method of A
return Object.values(this).includes(method);
}
}
const a = new A();
console.log(a.doesMethodBelongHere(a.methodA)); // should return true
Upvotes: 1
Views: 735
Reputation: 191986
You can use Object.getPrototypeOf()
to get the prototype. Then iterate the prototype properties using for...of
, and Object.getOwnPropertyNames()
. If the method is equal to one of the methods on the prototype return true
:
class A {
methodA() {
console.log('method of A');
}
doesMethodBelongHere(method) {
// get the prototype
const proto = Object.getPrototypeOf(this);
// iterate the prototype properties, and if one them is equal to the method's reference, return true
for(const m of Object.getOwnPropertyNames(proto)) {
const prop = proto[m];
if(typeof(prop) === 'function' && prop === method) return true;
}
return false;
}
}
const a = new A();
Object.assign(a, { anotherMethod() {} });
a.anotherMethod2 = () => {};
console.log(a.doesMethodBelongHere(a.methodA)); // should return true
console.log(a.doesMethodBelongHere(a.anotherMethod)); // should return false
console.log(a.doesMethodBelongHere(a.anotherMethod2)); // should return false
Extended classes:
This solution will also handle methods that comes from an extended class:
class A {
methodA() {
console.log('method of A');
}
doesMethodBelongHere(method) {
let proto = this;
// iterate the prototypes chain
while (proto = Object.getPrototypeOf(proto), proto && proto !== Object) {
// iterate the prototype properties, and if one them is equal to the method's reference, return true
for (const m of Object.getOwnPropertyNames(proto)) {
const prop = proto[m];
if (typeof(prop) === 'function' && prop === method) return true;
}
}
return false;
}
}
class B extends A {}
class C extends B {}
const c = new C();
Object.assign(c, {
anotherMethod() {}
});
c.anotherMethod2 = () => {};
console.log(c.doesMethodBelongHere(c.methodA)); // should return true
console.log(c.doesMethodBelongHere(c.anotherMethod)); // should return false
console.log(c.doesMethodBelongHere(c.anotherMethod2)); // should return false
Upvotes: 3
Reputation: 889
I'd suggest to use the following implementation:
A.prototype
, but in a more generic approach) in order to iterate class methods.Using Array.some, find whether (1) includes the name of the given method.
class A {
constructor() {
this.a = 2;
this.bb = 3;
}
methodA() {
console.log('method of A');
}
doesMethodBelongHere(method) {
// it should return true if `method` argument is a method of A
return this.constructor.prototype[method.name] === method;
}
}
Upvotes: 0
Reputation: 880
You can use typeof
operator
let isfn = "function" === typeof ( a.methodA );//isfn should be true
isfn = "function" === typeof ( a["methodA"] );//isfn should be true
isfn = "function" === typeof ( a["methodAX"] );//isfn should be false
doesMethodBelongHere( method ) {
return "function" === typeof ( this[method.name] )
}
Upvotes: 0
Reputation: 1063
class A {
constructor() {
this.methodA = this.methodA.bind(this);
this.doesMethodBelongHere = this.doesMethodBelongHere.bind(this);
}
methodA() {
console.log('method of A');
}
doesMethodBelongHere(method) {
// it should return true if `method` argument is a method of A
return Object.values(this).includes(method);
}
}
const a = new A();
console.log(a.doesMethodBelongHere(a.methodA)); // should return true
This was not bound to your class in your doesMethodBelongHere
.
Upvotes: 0