《TypeScript图形渲染实战:2D架构设计与实现》 —3.2.5 函数调用时this指向的Demo演示
3.2.5 函数调用时this指向的Demo演示
为了更好地了解TypeScript / JavaScript在函数调用时this到底指向哪里,使用手动编译TS代码方式来演示一个Demo,新建一个testThis.ts的文件,输入如下代码:
class TestThis {
// 编写一个打印this的方法
public printCB ( msec : number ) : void {
// 直接将this打印到console控制台
console.log(this);
}
// 构造函数
public constructor ( ) {
// 将this . printCB作为参数传递给requestAnimationFrame方法
window . requestAnimationFrame ( this . printCB ) ;
}
}
// 生成TestThis的一个实例对象,该对象的构造函数会调用
// window . requestAnimationFrame方法
new TestThis ( ) ;
在VS Code中打开集成终端,输入:tsc ./testThis.ts,将testThis.ts编译(转译)成非严格模式下的testThis.js源码,然后使用第1章中安装的Open In Browser插件运行HTML页面(该HTML文件使用testThis.js)后,会发现printCB打印出来的this是Window对象,如图3.8所示。
图3.8 非严格模式下this指向HTML DOM Window对象
在编译(转译)出来的testThis.js的第一行加入" use strict "后,代码如下:
"use strict" ; // 使用严格模式,来测试一下this指向问题
var TestThis = /** @class */ ( function ( ) {
function TestThis ( ) {
window . requestAnimationFrame ( this . printCB ) ;
}
TestThis . prototype . printCB = function ( msec ) {
console . log ( this ) ;
};
return TestThis ;
} ( ) ) ;
new TestThis ( ) ;
运行严格模式下的JS代码会发现,此时this打印出来的是null值,如图3.9所示。
图3.9 严格模式下this指向null值
如果不使用箭头函数,并且要确保this指向正确的对象(例如在本Demo中,想让this指向TestThis类的实例对象),可以使用函数对象的bind方法。具体代码如下:
// 构造函数
public constructor ( ) {
// printCB是一个成员方法,也是一个函数对象
// 因此printCB也具有bind方法
// 使用bind ( this )来绑定this对象
// 由于在constructor函数中,此时的this是指向TestThis类的实例对象的
// 这样printCB方法中的this指向的是printCB . bind ( this )中的this对象
window . requestAnimationFrame ( this . printCB . bind ( this ) ) ;
}
运行上述代码后,printCB中this指向的是TestThis类的实例对象,如图3.10所示。
图3.10 使用函数对象的bind方法绑定this
由此可见,也可以在Application类的成员方法start和step中使用bind进行绑定,就能让this正确地指向Application类的实例对象。
最后以Application和TestThis Demo为例子来总结一下,当一个回调函数或方法被绑定和调用时,可以按照如下顺序来确定this指向的问题:
* 如果使用了箭头函数,this指向的是当前类的实例对象,例如Application中代码所示。
* 如果使用函数对象的bind方法并绑定当前类的实例,那么this也指向当前类的实例对象,例如TestThis中bind函数调用所示。
* 如果没有使用上述两种方式,并且在非严格模式下,则this指向的是Window对象,例如TestThis中非严格模式Demo所示。
* 如果没有使用上述两种方式,并且在严格模式下("use strict"),则this指向null值。
- 点赞
- 收藏
- 关注作者
评论(0)