method = TypeError中的TypeScript调用方法:this.print不是函数

时间:2017-01-26 10:32:01

标签: javascript typescript webpack ecmascript-6

我有一个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);
  }
}

和app.ts文件:

export class App {
    constructor() {

    }
    private print = (str: string) => console.log(str);
    init(){
        this.print('test');
    }
}

当我使用这个tsconfig.json在webpack中使用ts-loader运行它时:

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "sourceMap": true,
        "lib": ["es5", "dom", "es2015.iterable"]
    }
}

我收到错误:Uncaught TypeError:this.print不是函数     在HTMLDocument.App.init(app.ts:17)

我尝试将该方法创建为私有打印(str){console.log(str); } 但这并没有解决它。

如何在init()方法中使用方法调用?

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

2 个答案:

答案 0 :(得分:3)

问题是你传递了new App().init而没有绑定它,当它被执行时this不是你想象的那样。

你应该这样做:

let app = new App();
ready(app.init.bind(app));

另一种选择:

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

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

    init() {
        this.print('test');
    }
}

或者您可以使用箭头功能:

export class App {
    constructor() {}

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

    init = () => {
        this.print('test');
    }
}

带有箭头功能的东西是它不会将方法放在类的原型上,而是将它添加为实例的属性。
在大多数情况下,这很好,但是如果您正在计划对App类进行子类化并覆盖init方法,那么您在调用super.init时会出现问题

答案 1 :(得分:1)

最简单的解决方案是编写

import { App } from './app';
const app = new App();
ready(() => app.init());

这不会影响继承或原型,也不会以任何方式改变类App的行为。

尽管如此,Nitzan Tomers的回答包含了对学习和理解非常重要的有价值的信息。