Javascript method=TypeError中的TypeScript调用方法:this.print不是函数
我有一个main.ts文件:Javascript method=TypeError中的TypeScript调用方法:this.print不是函数,javascript,typescript,webpack,ecmascript-6,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文件:
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加载程序运行它时:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"lib": ["es5", "dom", "es2015.iterable"]
}
}
我收到错误:未捕获类型错误:this.print不是函数
位于HTMLDocument.App.init(App.ts:17)
我已经尝试将该方法创建为privateprint(str){console.log(str);}
但这并没有解决问题
如何使init()方法中的方法调用正常工作
编辑:忘记添加,我正在运行webpack v。1.14.0和TypeScript 2.1.5(也尝试使用2.1.4)问题是,您正在传递
新应用().init
,但没有绑定它,执行时这个不是您所认为的
您应该这样做:
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');
}
}
不过,arrow函数的问题是,它不会将方法放在类的原型上,而是将其添加为实例的属性。
在大多数情况下,这很好,但是如果您计划对App
类进行子类化并重写init
方法,那么调用super.init
时就会遇到问题,最简单的解决方案是编写
import { App } from './app';
const app = new App();
ready(() => app.init());
这不会影响继承或原型,也不会以任何方式更改类App
的行为
尽管如此,Nitzan Tomers的回答包含了对学习和理解非常重要的宝贵信息。这是完全正确的。另一个选择是传递app.init()
谢谢,我确实忘记了将init方法也设为arrow函数。我可以确认其他选项也有效。好东西!