method = TypeError: this.print is not a function 中的 TypeScript 调用方法

App*_*ons 2 javascript typescript ecmascript-6 webpack

我有一个 main.ts 文件:

import { App } from './app';
import './styles.scss';

ready(new App().init);

function ready(fn) {
  if (document.readyState !== 'loading'){
    fn();
  } else {
    document.addEventListener('DOMContentLoaded', fn);
  }
}
Run Code Online (Sandbox Code Playgroud)

和一个 app.ts 文件:

export class App {
    constructor() {

    }
    private print = (str: string) => console.log(str);
    init(){
        this.print('test');
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用 webpack 中的 ts-loader 使用此 tsconfig.json 运行此命令时:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "lib": ["es5", "dom", "es2015.iterable"]
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到错误: Uncaught TypeError: this.print is not a function at HTMLDocument.App.init (app.ts:17)

我尝试将该方法创建为 private print(str){ console.log(str); 但这并没有解决问题。

如何让 init() 方法中的方法调用起作用?

编辑:忘记添加,我正在运行 webpack v.1.14.0 和 TypeScript 2.1.5(也尝试过 2.1.4)

Nit*_*mer 5

问题是您传递的是new App().init而不绑定它,并且当它执行时,它this不是您想象的那样。

你应该做这个:

let app = new App();
ready(app.init.bind(app));
Run Code Online (Sandbox Code Playgroud)

另外一个选择:

export class App {
    constructor() {
        this.init = this.init.bind(this);
    }

    private print = (str: string) => console.log(str);

    init() {
        this.print('test');
    }
}
Run Code Online (Sandbox Code Playgroud)

或者您可以使用箭头函数:

export class App {
    constructor() {}

    private print = (str: string) => console.log(str);

    init = () => {
        this.print('test');
    }
}
Run Code Online (Sandbox Code Playgroud)

但箭头函数的问题在于,它不会将方法放在类的原型上,而是将其添加为实例的属性。
在大多数情况下这很好,但是如果您计划App子类化该类并覆盖该init方法,那么您将在调用时遇到问题super.init