클래스의 함수 (메소드) 가져 오기
이 질문에 이미 답변이 있습니다.
- ES6 수업 방법 반복 9 답변
ES6 클래스의 속성과 기능을 동적으로 가져와야합니다. 이것이 가능할까요?
for ... in 루프를 사용하면 클래스 인스턴스의 속성 만 반복합니다.
class Foo {
constructor() {
this.bar = "hi";
}
someFunc() {
console.log(this.bar);
}
}
var foo = new Foo();
for (var idx in foo) {
console.log(idx);
}
산출:
bar
이 함수는 모든 함수를 가져옵니다. 상속 여부, 열거 가능 여부. 모든 기능이 포함되어 있습니다.
function getAllFuncs(obj) {
var props = [];
do {
props = props.concat(Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));
return props.sort().filter(function(e, i, arr) {
if (e!=arr[i+1] && typeof obj[e] == 'function') return true;
});
}
테스트 수행
getAllFuncs([1,3]);
콘솔 출력 :
["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__"]
노트
기호를 통해 정의 된 함수는 반환하지 않습니다.
클래스의 멤버는 열거 할 수 없습니다 . 이를 얻으려면 다음을 사용해야합니다 Object.getOwnPropertyNames
.
var propertyNames = Object.getOwnPropertyNames(Object.getPrototypeOf(foo));
// or
var propertyNames = Object.getOwnPropertyNames(Foo.prototype);
물론 이것은 상속 된 메서드를 얻지 못할 것입니다. 그들 모두를 줄 수있는 방법은 없습니다. 프로토 타입 체인을 탐색하고 각 프로토 타입의 속성을 개별적으로 가져와야합니다.
ES6는 코드를 좀 더 깔끔하게 만드는 Reflection을 추가합니다.
function getAllMethodNames(obj) {
let methods = new Set();
while (obj = Reflect.getPrototypeOf(obj)) {
let keys = Reflect.ownKeys(obj)
keys.forEach((k) => methods.add(k));
}
return methods;
}
/// a simple class hierarchy to test getAllMethodNames
// kind of like an abstract base class
class Shape {
constructor() {}
area() {
throw new Error("can't define area for generic shape, use a subclass")
}
}
// Square: a shape with a sideLength property, an area function and getSideLength function
class Square extends Shape {
constructor(sideLength) {
super();
this.sideLength = sideLength;
}
area() {
return this.sideLength * this.sideLength
};
getSideLength() {
return this.sideLength
};
}
// ColoredSquare: a square with a color
class ColoredSquare extends Square {
constructor(sideLength, color) {
super(sideLength);
this.color = color;
}
getColor() {
return this.color
}
}
let temp = new ColoredSquare(2, "red");
let methods = getAllMethodNames(temp);
console.log([...methods]);
@MuhammadUmer 답변에는 몇 가지 문제가 있었기 때문에 (기호, 색인 i+1
, Object
방법 목록 등) 영감을 얻었습니다.
(ES6로 컴파일 된 경고 Typescript)
const getAllMethods = (obj) => {
let props = []
do {
const l = Object.getOwnPropertyNames(obj)
.concat(Object.getOwnPropertySymbols(obj).map(s => s.toString()))
.sort()
.filter((p, i, arr) =>
typeof obj[p] === 'function' && //only the methods
p !== 'constructor' && //not the constructor
(i == 0 || p !== arr[i - 1]) && //not overriding in this prototype
props.indexOf(p) === -1 //not overridden in a child
)
props = props.concat(l)
}
while (
(obj = Object.getPrototypeOf(obj)) && //walk-up the prototype chain
Object.getPrototypeOf(obj) //not the the Object prototype methods (hasOwnProperty, etc...)
)
return props
}
이 함수는 상속 된 것을 포함하여 클래스 인스턴스의 모든 메서드를 나열 하지만 생성자와 Object 프로토 타입의 메서드를 나열 합니다 .
테스트
함수는
[ 'asyncMethod',
'echo',
'generatorMethod',
'ping',
'pong',
'anotherEcho' ]
TestClass
(typescript) 인스턴스의 메서드 나열
class Echo {
echo(data: string): string {
return data
}
anotherEcho(data: string): string {
return `Echo ${data}`
}
}
class TestClass extends Echo {
ping(data: string): string {
if (data === 'ping') {
return 'pong'
}
throw new Error('"ping" was expected !')
}
pong(data: string): string {
if (data === 'pong') {
return 'ping'
}
throw new Error('"pong" was expected !')
}
//overridden echo
echo(data: string): string {
return 'blah'
}
async asyncMethod(): Promise<string> {
return new Promise<string>((resolve: (value?: string) => void, reject: (reason?: any) => void) => {
resolve('blah')
})
}
* generatorMethod(): IterableIterator<string> {
yield 'blah'
}
}
클래스의 멤버를 열거 가능하게 만들려면 Symbol.iterator를 사용할 수 있습니다.
나는 (상속 된 것을 포함하여) 허용 된 모든 객체 메소드를 얻어야했다. 그래서 "Enumerable"클래스와 그로부터 상속받은 모든 기본 클래스를 만들었습니다.
class Enumerable {
constructor() {
// Add this for enumerate ES6 class-methods
var obj = this;
var getProps = function* (object) {
if (object !== Object.prototype) {
for (let name of Object.getOwnPropertyNames(object)) {
let method = object[name];
// Supposedly you'd like to skip constructor and private methods (start with _ )
if (method instanceof Function && name !== 'constructor' && name[0] !== '_')
yield name;
}
yield* getProps(Object.getPrototypeOf(object));
}
}
this[Symbol.iterator] = function*() {
yield* getProps(obj);
}
// --------------
}
}
참고URL : https://stackoverflow.com/questions/31054910/get-functions-methods-of-a-class
'IT TIP' 카테고리의 다른 글
char * envp []는 main () 휴대용에 대한 세 번째 인수입니다. (0) | 2020.12.08 |
---|---|
Laravel 5에서 예외 / 누락 된 페이지를 어떻게 잡나요? (0) | 2020.12.07 |
Kotlin에 동시성 키워드가없는 이유는 무엇입니까? (0) | 2020.12.07 |
ASP.NET 컨트롤에 해당하는 HTML 태그 (0) | 2020.12.07 |
치명적인 오류 : 정의되지 않은 함수 mb_strlen () 호출 (0) | 2020.12.07 |