TypeScript基础入门 - 函数 - this(三)

转载javascript

TypeScript基础入门 - 函数 - this(三)

项目实践仓库java

https://github.com/durban89/typescript_demo.git
tag: 1.2.4

为了保证后面的学习演示须要安装下ts-node,这样后面的每一个操做都能直接运行看到输出的结果。node

npm install -D ts-node

后面本身在练习的时候能够这样使用git

npx ts-node 脚本路径

函数

this

学习如何在JavaScript里正确使用this就比如一场成年礼。 因为TypeScript是JavaScript的超集,TypeScript程序员也须要弄清 this工做机制而且当有bug的时候可以找出错误所在。 幸运的是,TypeScript能通知你错误地使用了 this的地方。 若是你想了解JavaScript里的 this是如何工做的,那么首先阅读Yehuda Katz写的Understanding JavaScript Function Invocation and "this"。 Yehuda的文章详细的阐述了 this的内部工做原理,所以这里只作简单介绍。程序员

this参数在回调函数里

继续上篇文章【TypeScript基础入门 - 函数 - this(二)github

咱们也看到过在回调函数里this报错的状况,当你将一个函数传递到某个库函数里稍后会被调用时。 由于当回调被调用的时候,它们会被当成一个普通函数调用, this将为undefined。 稍作改动,你就能够经过 this参数来避免错误。 首先,库函数的做者要指定 this的类型,以下实例typescript

interface UIElement {
    addClickListener(onclick: (this: void, e: Event) => void): void;
}

this: void表示addClickListener指望onclick是一个不须要此类型的函数。
其次,用这个注释你的调用代码,以下所示npm

interface UIElement {
    addClickListener(onclick: (this: void, e: Error) => void): void;
}

class Handler {
    info: string;
    onClickBad(this: Handler, e: Error) {
        // oops, used this here. using this callback would crash at runtime
        this.info = e.message;
    }
}
let h = new Handler();
let uiElement: UIElement = {
    addClickListener(onclick: (this: void, e: Error) => void) {
        // do something
    }
};

uiElement.addClickListener(h.onClickBad); // 这里会报错

指定了this类型后,显式声明onClickBad必须在Handler的实例上调用。 而后TypeScript会检测到 addClickListener要求函数带有this: void。 咱们添加另一个函数作下对比,以下函数

interface UIElement {
    addClickListener(onclick: (this: void, e: Error) => void): void;
}

class Handler {
    info: string;
    onClickBad(this: Handler, e: Error) {
        this.info = e.message;
    }
    onClickGood(this: void, e: Error) {
        console.log('点击了!');
    }
}
let h = new Handler();
let uiElement: UIElement = {
    addClickListener(onclick: (this: void, e: Error) => void) {
        // do something
    }
};

uiElement.addClickListener(h.onClickGood);

经过将h.onClickBad更换为h.onClickGood,就能正常调用。
由于onClickGood指定了this类型为void,所以传递addClickListener是合法的。 固然了,这也意味着不能使用 this.info. 若是你二者都想要,你不得不使用箭头函数了,以下oop

interface UIElement {
    addClickListener(onclick: (this: void, e: Error) => void): void;
}

class Handler {
    info: string;
    onClickGood = (e: Error) => { this.info = e.message }
}

let h = new Handler();
let uiElement: UIElement = {
    addClickListener(onclick: (this: void, e: Error) => void) {
        // do something
    }
};

uiElement.addClickListener(h.onClickGood);

这是可行的由于箭头函数不会捕获this,因此你老是能够把它们传给指望this: void的函数。 缺点是每一个 Handler对象都会建立一个箭头函数。 另外一方面,方法只会被建立一次,添加到 Handler的原型链上。 它们在不一样 Handler对象间是共享的。


本实例结束实践项目地址

https://github.com/durban89/typescript_demo.git
tag: 1.2.5
相关文章
相关标签/搜索