我正在寻找将类方法传递给函数的可能性,然后该函数可以在该类的实例上执行该函数。 像这样的伪代码:(注意这是一个抽象的例子)
class Foo {
public somefunc() {
// do some
}
public anyfunc() {
// do any
}
}
function bar(obj: Foo ,func: "Foo.method") { // "that's what im looking for"
obj.func();
}
bar(new Foo(), Foo.somefunc); // do some
bar(new Foo(), Foo.anyfunc); // do any
有可能这样做吗?
我知道我可以做类似的事情:
class Foo {
static somefunc(fooObj: Foo) {
// do some
}
static anyfunc(fooObj: Foo) {
// do any
}
}
interface func {
(fooObj: Foo);
}
function bar(obj: Foo, fn: func) {
fn(obj);
}
bar(new Foo(), Foo.somefunc); // do some
bar(new Foo(), Foo.anyfunc); // do any
但这涉及我不想要的静态函数。
这不会在编译时检查该函数是否来自
Foo
,但会执行其余操作:
class Foo {
public somefunc() {
// do some
}
public anyfunc() {
// do any
}
}
function bar(obj: Foo ,func: () => void) {
func.call(obj);
}
bar(new Foo(), Foo.prototype.somefunc); // do some
bar(new Foo(), Foo.prototype.anyfunc); // do any
TL;DR:TypeScript Playground,带演示的 Repo
优点:
this
上下文
传递实例的方法。public somefunc = () => { return this.prop; }
)-了解更多。thisArg
作为第二个参数(例如Array.prototype.map())。考虑以下代码:
class Foo {
private result: number = 42;
public func(this: Foo): number {
return this.result;
}
}
function action(): void {
console.log("Hello world!");
}
function bar(callbackFn: (this: void) => any, thisArg?: undefined): any;
function bar<T>(callbackFn: (this: T) => any, thisArg: T): any;
function bar<T, TResult>(callbackFn: (this: T) => TResult, thisArg: T): TResult {
return callbackFn.call(thisArg);
}
const foo = new Foo();
bar(action); // success
bar(foo.func); // ERROR: forgot to pass `thisArg`
bar(foo.func, foo); // success
请注意
Foo#func
的签名:
public func(this: Foo): number
它指出该函数应该在类实例的上下文中调用。这是解决方案的第一部分,它不会让您丢失
this
上下文。
第二部分是
bar
函数重载:
function bar(callbackFn: (this: void) => any, thisArg?: undefined): any;
function bar<T>(callbackFn: (this: T) => any, thisArg: T): any;
function bar<T, TResult>(callbackFn: (this: T) => TResult, thisArg: T): TResult
这可以让您传递泛型函数和实例方法。
您可以在 TypeScript 手册中了解有关这些主题的更多信息:
是的,像这样声明函数:
myfunction(action: () => void){
action();
}
从打字稿中这样称呼它:
myfunction(() => alert("hello"));
或者来自 javascript:
myfunction(function() { alert("hello"); });
也可以通过方法:
myfunction(this.someMethod);
我假设您正在寻找某种方法让 TypeScript 编译器强制 Foo 上存在给定的函数? 不幸的是,我认为没有办法做到这一点。 也许另一位 TypeScript 大师可以进来并更具体地回答这个问题,但我很确定这是你能得到的最接近的答案:
class Foo {
constructor(private name:string) { }
public somefunc() {
console.log("someFunc called on", this.name);
}
public anyfunc() {
console.log("anyFunc called on", this.name);
}
}
function bar(obj: Foo, func: string) {
if (obj[func] && obj[func] instanceof Function) {
obj[func]();
} else {
throw new Error("Function '" + func + "' is not a valid function");
}
}
bar(new Foo("foo1"), "somefunc"); // output: 'somefunc called on foo1'
bar(new Foo("foo2"), "anyfunc"); // output: 'anyfunc called on foo1'
bar(new Foo("foo3"), "badFunction"); // throws: Error: Function 'badFunction' is not a valid function
就我而言;根据问题的陈述,我可以这样做:
class Foo {
public constructor() {
this.welcome = this.welcome.bind(this)
}
public welcome(msg: string): void {
console.log(`hello ${msg}`)
}
}
function bar(msg: string, fn: void): void {
fn(msg)
}
const foo = new Foo()
bar('world', foo.welcome) // 'hello world'
此外,我应该指出,我受到了这个清晰的解释的启发。
希望有帮助!
您可以使用粗箭头功能。他们不应该失去“这个”
class Foo {
public somefunc = () => {
// do some
}
public anyfunc = () => {
// do any
}
}
在我看来,这种情况应该使用门面设计模式。
当您创建一个复杂的库、工具或系统时,由许多函数和/或类组成;它变得难以理解和依赖。所以你应该实现一个提供简单统一接口的类。
class Foo{
public somefunc() {
console.log("some")
}
public anyfunc() {
console.log("any")
}
};
class FuncFacade {
getFunc(obj: any, func_name: string) {
switch (func_name) {
case obj.somefunc.name: {
return obj.somefunc;
}
case obj.anyfunc.name: {
return obj.anyfunc;
}
default: {
throw new Error("No such func!");
}
}
}
}
let ff = new FuncFacade();
function bar(obj: Foo, func_name: string) {
ff.getFunc(obj,func_name)();
}
bar(new Foo(), Foo.prototype.anyfunc.name);
也许这不是你所要求的,但这就是它应该的样子。
这取决于您特定用例的具体情况,但这是其他答案尚未涵盖的另一个选项。
其他答案不适用于我的用例,因为我有很多使用
anyFunc
方法的类,并且我希望它可以与其中任何一个一起使用。
这对我的用例有用:
class EnglishGreeting {
private readonly greeting = 'Hello ';
public greet(name: string): void {
console.log(this.greeting + name);
}
}
class FrenchGreeting {
private readonly greeting = 'Bonjour ';
public greet(name: string): void {
console.log(this.greeting + name);
}
}
function bar(greeter: { greet:(name: string) => void }) {
greeter.greet('Joe')
}
bar(new EnglishGreeting()); // Prints "Hello Joe"
bar(new FrenchGreeting()); // Prints "Bonjour Joe"
Javascript 允许这样做,但不确定这是否是你想要的?
class Foo {
public someFunc(name:string){
return "Hello, " + name;
}
function bar(funcName: string) {
return eval(funcName);
}
console.log(bar("new Foo().someFunc('erik')"));