我有一个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)答案 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的回答包含了对学习和理解非常重要的有价值的信息。