Missing _this definition.

Topics: Language Specification
Oct 8, 2012 at 5:17 PM

Within a class using jQuery's .ajax function I did this:

        connect(callback?: (connected: bool) => void) {
            $.ajax(this.url + "/connect", $.extend(true, {}, this.ajaxSettings, {
                success: (data) => {
                    this.errorChecker(data, (data) => {
                        if (callback != null) {
                            callback(data);
                        }
                    });
                },
                timeout: this.timeout,
                error: () => {
                    if (callback != null) {
                        callback(false);
                    }
                }
            }));
        }

 

 

Which the type script compiler compiles into this:

            VAS.prototype.connect = function (callback) {
                $.ajax(this.url + "/connect", $.extend(true, {
                }, this.ajaxSettings, {
                    success: function (data) {
                        _this.errorChecker(data, function (data) {
                            if(callback != null) {
                                callback(data);
                            }
                        });
                    },
                    timeout: this.timeout,
                    error: function () {
                        if(callback != null) {
                            callback(false);
                        }
                    }
                }));
            };

Note the line with

_this.errorChecker

The compiler correctly notices that _this should refer to this instance of the object, but it fails to include the _this=this line at the start of the function. Is this a bug? If I remove the $.extend part and just create the ajaxSettings object as a whole, it correctly adds the _this = this line.
Oct 8, 2012 at 7:49 PM

It is not the extend, it is the extra parameter to extend that breaks it:

$.extend(true, {}, { success: (data) => { this.process(data); }});

works fine.

I played a bit with the definition of extend, turn out if definition variant is used where the interface is defined with variable number of parameters and the actual parameter count exceeds the one in the definition, the _this variable is not created.

for example we an change the definition of extend as follow:

 extend(deep: bool, target: any, obj1: any, obj2: any, obj3: any, ...objs: any[]): Object;

 extend(deep: bool, target: any, obj1: any, obj2: any, obj3: any, ...objs: any[]): Object;

and then define the call as:

  connect(url) {
    $.ajax(this.url + '/conect', $.extend(true, {one: 1}, { two: 2}, {three: 3},{
      four: 4},{
      success: (data:string) => {
        this.process(data);
      }
    }));
  }

Because the parameters in the call are less than or equal to the ones in the definition, _this is created, If we add one more object (i.e. hit beyond the defined ones even though the last one is defined as many) we do not get the _this assignment.

 

Clearly a bug when compiling to calls with variable length parameters.

 

You should file a bug.

Coordinator
Oct 9, 2012 at 6:39 PM

Tracking with issue: http://typescript.codeplex.com/workitem/181

Thanks for narrowing down the problem, pstj.