How can I preserve lexical scope in TypeScript with a callback function

前端 未结 5 2085
小蘑菇
小蘑菇 2020-11-29 01:01

I have a TypeScript class, with a function that I intend to use as a callback:

removeRow(_this:MyClass): void {
    ...
    // \'this\' is now the window obj         


        
5条回答
  •  庸人自扰
    2020-11-29 01:32

    This is sort of a cross post from another answer (Is there an alias for 'this' in TypeScript?). I re-applied the concept using the examples from above. I like it better than the options above because it explictly supports "this" scoping to both the class instance as well as the dynamic context entity that calls the method.

    There are two versions below. I like the first one because the compiler assists in using it correctly (you won't as easily try to misuse the callback lambda itself as the callback, because of the explicitly typed parameter).

    Test it out: http://www.typescriptlang.org/Playground/

    class Test {
    
        private testString: string = "Fancy this!";
    
        // Define the method signature here.
        removeRowLambdaCallback(outerThis: Test): {(): void} {
            alert("Defining callback for consumption");
            return function(){
                alert(outerThis.testString); // lexically scoped class instance
                alert(this); // dynamically scoped context caller
                // Put logic here for removing rows. Can refer to class
                // instance as well as "this" passed by a library such as JQuery or D3.
            }
        }
        // This approach looks nicer, but is more dangerous
        // because someone might use this method itself, rather
        // than the return value, as a callback.
         anotherRemoveRowLambdaCallback(): {(): void} {
            var outerThis = this;
            alert("Defining another callback for consumption");
            return function(){
                alert(outerThis.testString); // lexically scoped class instance
                alert(this); // dynamically scoped context caller
                // Put logic here for removing rows. Can refer to class
                // instance as well as "this" passed by a library such as JQuery or D3.
            }
        }
    }
    
    var t = new Test();
    var callback1 = t.removeRowLambdaCallback(t);
    var callback2 = t.anotherRemoveRowLambdaCallback();
    
    callback1();
    callback2();
    

提交回复
热议问题