无法从TypeScript中的构造函数调用私有函数

时间:2018-09-05 11:28:45

标签: typescript

我有一个简单的TypeScript类,带有一个私有函数,当用户单击按钮时应调用该私有函数。 click事件通过构造函数中的jQuery click()事件绑定

HTML

<div id="foobar">
  <h2>Foo</h2>
  <button type="button">Bar</button>
</div>

TS

$(() => {
    var foo = new Bar($("#foobar"));
})

class Bar {
    private view: JQuery;
    private button: JQuery;

    constructor(view: JQuery) {
            // Fields
        this.view = view;
        this.button = view.find("button");

        // Events
        this.button.click(() => { this.buttonClick() });
    }

    private buttonClick() {
        this.view.find("h2").css("background-color", "red");
    }
}

https://jsfiddle.net/z4vo5u5d/18781/

但是以某种方式,执行脚本时,控制台会抱怨buttonClick不是函数。我在这里想念什么?

我想这是"this" in TypeScript的问题。但我不知道为什么。

已编辑: 如@Amadan所述:

this.button.click(() => { this.buttonClick() });

incorrectly by jsfiddle翻译成

this.button.click(function () { this.buttonClick(); });

同时,typescriptlang.org / play上的编译器将其正确翻译为:

var _this = this;
...
this.button.click(function () { _this.buttonClick(); });

1 个答案:

答案 0 :(得分:-1)

我认为这是我要解决的范围问题。

在旧版本的TypeScript中,就像JSFiddle使用的那样,this的范围在您使用的所有地方都不相同。这是一个动态变量,它随调用位置而变化。按钮的事件功能中的this.buttonClick()等于按钮本身的buttonClick()功能,因为它属于Bar,因此它没有此功能。

尝试在const self = this;下方分配一个constructor(view: JQuery) {值,并在构造函数中将所有出现的this替换为self

这确保self求值的对象始终是对象本身,而不是当前上下文,这可能不是您要针对的对象。

class Bar {
    private view: JQuery;
    private button: JQuery;

    constructor(view: JQuery) {
        const self = this;

        // Fields
        self.view = view;
        self.button = view.find("button");

        // Events
        self.button.click(() => { self.buttonClick() });
    }

    private buttonClick() {
        this.view.find("h2").css("background-color", "red");
    }
}

That应该可以正常工作。我已经多次遇到这个问题。我已经习惯在我编写的每个函数中都声明const self = this;

已编辑: 如@Amadan所述:

this.button.click(() => { this.buttonClick() });

incorrectly by jsfiddle翻译成

this.button.click(function () { this.buttonClick(); });

同时,typescriptlang.org / play上的编译器将其正确翻译为:

var _this = this;
...
this.button.click(function () { _this.buttonClick(); });