Get functions (methods) of a class
This function will get all functions. Inherited or not, enumerable or not. All functions are included.
function getAllFuncs(toCheck) {
const props = [];
let obj = toCheck;
do {
props.push(...Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));
return props.sort().filter((e, i, arr) => {
if (e!=arr[i+1] && typeof toCheck[e] == 'function') return true;
});
}
Do test
getAllFuncs([1,3]);
console output:
["constructor", "toString", "toLocaleString", "join", "pop", "push", "concat", "reverse", "shift", "unshift", "slice", "splice", "sort", "filter", "forEach", "some", "every", "map", "indexOf", "lastIndexOf", "reduce", "reduceRight", "entries", "keys", "constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "__defineGetter__", "__lookupGetter__", "__defineSetter__", "__lookupSetter__"]
Note
It doesn't return functions defined via symbols;
How do I get list of methods in a Python class?
An example (listing the methods of the optparse.OptionParser
class):
>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
('add_option', <unbound method OptionParser.add_option>),
('add_option_group', <unbound method OptionParser.add_option_group>),
('add_options', <unbound method OptionParser.add_options>),
('check_values', <unbound method OptionParser.check_values>),
('destroy', <unbound method OptionParser.destroy>),
('disable_interspersed_args',
<unbound method OptionParser.disable_interspersed_args>),
('enable_interspersed_args',
<unbound method OptionParser.enable_interspersed_args>),
('error', <unbound method OptionParser.error>),
('exit', <unbound method OptionParser.exit>),
('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
...
]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...
Notice that getmembers
returns a list of 2-tuples. The first item is the name of the member, the second item is the value.
You can also pass an instance to getmembers
:
>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...
How to get all functions of es6 class instance
You have to call Object.getOwnPropertyNames()
on the prototype
property of the class.
class Test { methodA() {} methodB() {}}
console.log(Object.getOwnPropertyNames(Test.prototype))
Get class methods in typescript
You forget that TypeScript is Javascript. Remember that the TypeScript compiler compiles your code into Javascript.
So, as you normally do in Javascript, you can enumerate members on an object like this:
UtilityClass myclass = ...;
for (var member in myclass) { /* do something */ }
More advanced
If you want to make sure you don't get inherited members:
for (var member in myclass) {
if (myclass.hasOwnProperty(member)) {
/* do something */
}
}
Extract methods
If you want to make sure you get only methods (functions):
for (var member in myclass) { // For each member of the dictionary
if (typeof myclass[member] == "function") { // Is it a function?
if (myclass.hasOwnProperty(member)) { // Not inherited
// do something...
}
}
}
Reflection in TypeScript
As you can see the approaches require an instance to work on. You don't work on the class. Reflection is what you are trying to achieve in the context of OOP; however Javascript (which is not OOP) deals with it in a different way.
Getting all class methods in classes in current file in Python?
On Python 3, calling inspect.ismethod
on an attribute of a class that happens to be a function will always be False, because it will just be a plain function. function.__get__
only returns a method object when accessed as an attribute of an instance.
If you want to get all "methods" of the class just use inspect.isfunction
.
>>> class A:
... def __init__(self): pass
...
>>> A.__init__
<function A.__init__ at 0x7fd524dd2f80>
>>> inspect.ismethod(A.__init__)
False
>>> inspect.isfunction(A.__init__)
True
>>> inspect.ismethod(A().__init__)
True
Get methods of class in JavaScript
You can use Object.getOwnPropertyNames
and filter the instance
and static
methods:
class c { methodA(){} static methodB(){}
log(){console.log(/*methods*/);} static logStatic(){console.log(/*static methods*/)}}const instanceOnly = Object.getOwnPropertyNames(c.prototype) .filter(prop => prop != "constructor");console.log(instanceOnly);const staticOnly = Object.getOwnPropertyNames(c) .filter(prop => typeof c[prop] === "function");console.log(staticOnly);
Get return type of class method via method name in Typescript
Afaik ,there is no safe way to do what you want without changing function body or using type assertion.
In order to validate function arguments, first of all we need to obtain all method keys from Foo
:
class Foo {
var1: string = 'var1';
var2: string = 'var2';
hello(request: string) { }
world(request: number) { }
}
// This type reflects any function/method
type Fn = (...args: any[]) => any
type ObtainMethods<T> = {
[Prop in keyof T]: T[Prop] extends Fn ? Prop : never
}[keyof T]
// "hello" | "world"
type AllowedMethods = ObtainMethods<Foo>
Let's test it:
const executeFoo = <Method extends ObtainMethods<Foo>>(
methodName: Method
) => { }
executeFoo('hello') // ok
executeFoo('world') // ok
executeFoo('var1') // expected error
However, there is a problem with second argument:
const executeFoo = <Method extends ObtainMethods<Foo>>(
methodName: Method, parameter: Parameters<Foo[Method]>[0]
) => {
// Argument of type 'string | number' is not assignable to parameter of type 'never'. Type 'string' is not assignable to type 'never'.
foo[methodName](parameter)
}
As you might have noticed, there is an error.
Argument of type 'string | number' is not assignable to parameter of type 'never'.
Type 'string' is not assignable to type 'never'.
It is very important. If you try to call foo[methodName]()
you will see that this function expects never
as a type for first argument. This is because
Likewise, multiple candidates for the same type variable in contra-variant positions causes an intersection type to be inferred.
You can find more in my article, in the first part. This is because TS does not know which methodName
you are using exactly. Hence, TS compiler intersects all parameters from methods: string & number
because this is the only safe way to make function signature safe.
SO, it is very important what type of argument are you expect in your methods.
How to fix it ?
In this particular example, I believe using type assertion
is justified:
const executeFoo = <Method extends ObtainMethods<Foo>>(
methodName: Method, parameter: Parameters<Foo[Method]>[0]
) => {
(foo[methodName] as (arg: Parameters<Foo[Method]>[0]) => void)(parameter)
}
executeFoo('hello', 'str') // ok
executeFoo('world', 42) // ok
executeFoo('world', "42") // expected error
executeFoo('var1') // expected error
Playground
If you are interested in function argument inference you can check my blog
It is also possible to use conditional statement for type narrowing (works in TS >= 4.6)
type Fn = (...args: any[]) => any
type ObtainMethods<T> = {
[Prop in keyof T]: T[Prop] extends Fn ? Prop : never
}[keyof T]
// "hello" | "world"
type AllowedMethods = ObtainMethods<Foo>
type Values<T> = T[keyof T]
type AllowedArguments = {
[Method in AllowedMethods]: [Method, Parameters<Foo[Method]>[0]]
}
const foo = new Foo();
const executeFoo = (
...[name, arg]: Values<AllowedArguments>
) => {
if (name === 'hello') {
foo[name](arg)
} else {
foo[name](arg)
}
}
executeFoo('hello', 'str') // ok
executeFoo('world', 42) // ok
executeFoo('world', "42") // expected error
executeFoo('var1') // expected error
but it does not make much sense.
Can I get all methods of a class?
To know about all methods use this statement in console:
javap -cp jar-file.jar packagename.classname
or
javap class-file.class packagename.classname
or for example:
javap java.lang.StringBuffer
Get function reference of class (not object)
The methods defined with method syntax in the body of a class
construct that aren't marked static
are prototype methods and so they're on Temp.prototype
, not Temp
itself. So that's where you'd update them:
Temp.prototype.hi = modifyMethod(Temp.prototype.hi);
Only static methods end up on Temp
itself.
You may see other functions created within the class
body using the class fields proposal's syntax:
class Temp {
hi = () => {
//
};
}
Those are instance methods. They're created by the constructor, and re-created for each instance, roughly as though they'd been written like this:¹
class Temp {
constructor() {
this.hi = () => {
//
};
}
}
You can't wrap those until/unless an instance is created, as they're instance-specific.
So to wrap up, consider:
class Temp {
static staticMethod() {
// ...
}
prototypeMethod() {
// ...
}
instanceMethod = () => {
// ...
};
constructor() {
this.anotherInstanceMethod = () => {
// ...
};
this.yetAnotherInstanceMethod = function {
// ...
};
}
}
That class shows the three types of methods:
- Static Methods, such as
staticMethod
, which you'll find onTemp
(e.g.,Temp.staticMethod
); - Prototype Methods, such as
prototypeMethod
, which you'll find onTemp.prototype
(e.g.,Temp.prototype.prototypeMethod
); and - Instance Methods, such as
instanceMethod
,anotherInstanceMethod
, andyetAnotherInstanceMethod
, which you'll find on the instances themselves, if/when any instances are created
¹ Technically, they're created as though with Object.defineProperty
like this:
class Temp {
constructor() {
Object.defineProperty(this, "hi", {
value: () => {
//
},
writable: true,
configurable: true,
enumerable: true
});
}
}
...not via simple assignment. I used simple assignment in the example to keep it...simple. :-)
Related Topics
Map and Filter an Array at the Same Time
How to 'Minify' JavaScript Code
How to Prevent Form from Submitting Multiple Times from Client Side
Adding Console.Log to Every Function Automatically
Javascript: Formatting a Rounded Number to N Decimals
Using JavaScript to Display a Blob
Chrome, JavaScript, Window.Open in New Tab
Failed to Execute 'Postmessage' on 'Domwindow': Https://Www.Youtube.Com !== Http://Localhost:9000
How to Transpose a JavaScript Object into a Key/Value Array
Need to Escape a Special Character in a Jquery Selector String
What Is Ajax and How Does It Work
New Es6 Syntax for Importing Commonjs/Amd Modules I.E. 'Import Foo = Require('Foo')'
Differencebetween JavaScript Promises and Async Await
Remove All Special Characters with Regexp
What Do Curly Braces Inside of Function Parameter Lists Do in Es6