Nanfeng

Notes on software development, code, and curious ideas

Preserving this in setTimeout and setInterval Callbacks

When a traditional function is passed directly to setTimeout or setInterval, it is invoked without the original object’s method-call context. Its this therefore does not reliably refer to the component instance.

Capture the instance

1
2
3
4
5
6
function startBroadcast() {
const that = this;
setInterval(function () {
console.log(that.msg);
}, 1000);
}

Bind the callback

1
2
3
4
5
function startBroadcast() {
setInterval(function () {
console.log(this.msg);
}.bind(this), 1000);
}

Use an arrow function

Arrow functions inherit this lexically from the surrounding scope and are usually the clearest TypeScript option:

1
2
3
4
5
function startBroadcast() {
setInterval(() => {
console.log(this.msg);
}, 1000);
}

How JavaScript chooses this

  • A function invoked with new receives the newly created object.
  • call, apply, and bind explicitly supply the receiver.
  • A method call such as obj.foo() uses obj as the receiver.
  • A plain function call uses undefined in strict mode and may use the global object in older non-strict behavior.
  • An arrow function does not create its own this; it inherits the surrounding value.

Store the timer ID and clear it when the Cocos Creator component is disabled or destroyed, or use the component’s schedule/unschedule APIs for lifecycle-aware timers.

+