[英]Typescript “this” instance is undefined in class
I found this and online and now trying to put it in TS. 我发现这个和在线,现在试图把它放在TS。
Running the following throws Uncaught TypeError: Cannot set property 'toggle' of null
运行以下抛出
Uncaught TypeError: Cannot set property 'toggle' of null
@Injectable()
export class HomeUtils {
private canvas: HTMLCanvasElement;
private context;
private toggle = true;
constructor() { }
public startNoise(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.context = canvas.getContext('2d');
this.resize();
this.loop();
}
private resize() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
}
private loop() {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(this.loop);
return;
}
this.noise();
requestAnimationFrame(this.loop);
}
private noise() {
const w = this.context.canvas.width;
const h = this.context.canvas.height;
const idata = this.context.createImageData(w, h);
const buffer32 = new Uint32Array(idata.data.buffer);
const len = buffer32.length;
let i = 0;
for (; i < len;) {
buffer32[i++] = ((255 * Math.random()) | 0) << 24;
}
this.context.putImageData(idata, 0, 0);
}
}
I'm lost. 我迷路了。
Methods do not capture this
and are dependent on the caller to call them with the correct this
. 方法不抓住
this
和依赖于呼叫方打电话给他们以正确的this
。 So for example: 例如:
this.loop() // ok
let fn = this.loop;
fn(); // Incorect this
fn.apply(undefined) // Undefined this
Since you pass loop
to another function requestAnimationFrame
you need to ensure that this
is captured from the declaration context and not decided by requestAnimationFrame
: 既然你通过
loop
到另一个函数requestAnimationFrame
你需要确保this
是从声明上下文中获取,而不是由决定requestAnimationFrame
:
You can either pass an arrow function to requestAnimationFrame
您可以将箭头函数传递给
requestAnimationFrame
private loop() {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(() => this.loop());
return;
}
this.noise();
requestAnimationFrame(() => this.loop());
}
Or you can make loop an arrow function not a method: 或者你可以使循环箭头函数而不是方法:
private loop = () => {
this.toggle = false;
if (this.toggle) {
requestAnimationFrame(this.loop);
return;
}
this.noise();
requestAnimationFrame(this.loop);
}
The second approach has the advantage of not creating a new function instance on each call to requestAnimationFrame
, since this will be called a lot, you might want to go with the second version to minimize memory allocations. 第二种方法的优点是不会在每次调用
requestAnimationFrame
创建新的函数实例,因为这将被调用很多,您可能希望使用第二个版本来最小化内存分配。
It's the call to requestAnimationFrame
. 这是对
requestAnimationFrame
的调用。 You are passing a function not bound to a context, and so, inside that call to loop
there is no this
. 您正在传递一个未绑定到上下文的函数,因此,在该
loop
调用中没有this
。
Change the call to: 将通话更改为:
requestAnimationFrame(() => this.loop());
Arrow functions, contrarily to normal functions, are bound to this
. 与正常功能相反,箭头功能与
this
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.