问题
TypeScript在配置表需要直接配置某个类的指定方法。比如[“ClassA”,“Show”]代表ClassA.Show()。
代码如下
class ClassA {
private m_value: number = 0;
private static s_name: string = "";
public static Show() {
this.s_name = "l2xin";
console.log("ClassA.Show():", this)
ClassA.Init();
}
public static ShowFunc = function () {
this.s_name = "l2xin";
console.log("ClassA.ShowFunc():", this)
ClassA.Init();
}
private SetValue() {
this.m_value = 2;
}
private static Init() {
}
}
测试代码
function Test() {
let a: ClassA = new ClassA();
let myClass = window["ClassA"];
//ShowFunc中this为ClassA
myClass.Show();
//ShowFunc中this为ClassA
myClass.ShowFunc();
/**使用字符串获得方法 */
let func: Function = myClass["Show"];
//func执行时this为window
func();
//执行时this为ClassA 正常
func.call(myClass);
}
测试结果
-
myClass.Show();
-
myClass.ShowFunc();
-
let func: Function = myClass["Show"]; func.call(myClass);
ClassA.Show(): ƒ ClassA() { this.m_value = 0; }
-
let func: Function = myClass["Show"]; func();
ClassA.Show(): Window
前三种执行的结果都和预期相符,函数中的this都是ClassA。
最后一种func()中this代表的是Window。
分析
Ts和Js在一个方法中(如果是ts,这里仅限于非lambda表达式定义的方法)有使用this关键字,那么可以按照下面的优先级顺序来推断this指向的是什么:
- 如果这个函数是function#bind调用的结果,那么this指向的是传入bind的参数
- 如果函数是以foo.func()形式调用的,那么this值为foo
- 直接func(),如果是在严格模式下,this将为undefined,否则,this将是全局对象(浏览器环境里为window)
详细文档看这里:
Understanding JavaScript Function Invocation and “this”
综上,我理解Ts的this是这样:
- 调用x.func();则 func()中this就是x,
- 如果是匿名函数或者把函数类型变量,即let myFunc = x.func; myfunc中的this则根据上下文来决定,全局就为window。
对比lua的self.func() self:func()还有python的面向对象理解起来更有意思。
其他
下面这两种实现都可以满足需求
-
public static ShowFunc = function () {}
-
public static Show() {}
个人推荐使用第二种,Class内部实现会比较自然。
let func: Function = myClass["Show"];
func.call(myClass);