0

Long-time .Net developer here, tasked with converting a bunch of old JS code to new ES6 JS modules. I'm trying to run the (you would think) simple code below, but when jumpToVideoNew is called, this.allowVidJump in the delegate function doesn't have access to the class property allowVidJump. I'm trying to set a simple timed delay so calling code can't hammer the jumpToVideoNew function repeatedly. I understand the concept that the variable loses scope, but I've tried setting _this = this; and using _this in the delegate as well with no success. Also tried passing a reference to the variable in to the function and accessing it that way, but also no luck. Spending 2 hours on something this simple is reminding me why I steer clear of javascript when possible.

export class WebUtility {
    constructor() {
        this.allowVideoJump = true;
        this.delay = function () { this.allowVidJump = true; };
    }

    jumpToVideoNew() {
        if (this.allowVideoJump) {
            this.allowVideoJump = false;
            setTimeout(this.delay, 1000);
        }
    }
}
Ageonix
  • 1,748
  • 2
  • 19
  • 32

1 Answers1

1

Use an anonymous arrow function The function keyword in JS creates a new scope as well as a new this (the function you just defined === this), so this.allowVidJump is essentially (function() {}).allowVidJump in that scope

Try something like this:

export class WebUtility {
    constructor() {
        this.allowVideoJump = true;
        this.delay = () => { this.allowVidJump = true; }; // anonymous lambda
    }

    jumpToVideoNew() {
        if (this.allowVideoJump) {
            this.allowVideoJump = false;
            setTimeout(this.delay, 1000);
        }
    }
}
gabriel.hayes
  • 2,267
  • 12
  • 15
  • He already has an anonymous function. The difference here is that it's an **arrow** function. – Barmar Jan 24 '20 at 20:04
  • The context is not the function, it will be the global `window` object. – Barmar Jan 24 '20 at 20:06
  • That's the first time I've seen anyone call JS's function expressions "lambda" functions. The usual term is just "function expression", and they can either be named function expressions or anonymous function expressions, depending on whether you put a name after the `function` keyword. – Barmar Jan 24 '20 at 20:09
  • @Barmar wait, why is the context the global `window` object? If you can post a link/example explaining that in detail it'd be nice (I'm a new era-ish JS dev.. I've basically **always** used arrow functions after my first rodeo with the `function` keyword unless I need recursion) – gabriel.hayes Jan 24 '20 at 20:15
  • 1
    When you call a (non-arrow) function with the notation `object.func()` then the context is `object`. But if you just call it in the form `func()`, it uses the global context, which is `window` in browsers, some other global object in node.js. `setTimeout` doesn't have access to the original object, so it calls it the second way. – Barmar Jan 24 '20 at 20:17