3

I am little confused about using this in typescript, by looking at this code

class GoogleMapsClass {
    public map;

    constructor(selector) {
        var _this = this;
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4) {
                _this.map = this.responseText;
            }
        };
        xhttp.open("GET", "/test.php", false);
        xhttp.send();
    }
}

you can see that I am using a context-switch trick var _this = this;

I don't know if this is proper way to work with class fields in typescript, also I am worried that by using this trick I just duplicated memory so it is not good for performance, and overall code quality (I know that JS is not made for some heavy operations, but still, duplicating objects is most trivial mistake when it comes to optimizing code).

What is the most correct way to handle context switching?

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
Bartłomiej Sobieszek
  • 2,692
  • 2
  • 25
  • 40
  • How are you duplicating an object? You're creating a reference to an object so you can refer to it later. Not sure what you mean by saying JS is not made for some heavy operations. – Dave Newton Dec 27 '16 at 01:29
  • Your example code snippet is more an example of "why closure is useful" more so than a "trick" in my opinion. If you were looking for an alternative, you can use `.bind(this)` on your anonymous function. – therobinkim Dec 27 '16 at 01:32
  • JS is a client-side tool that won't always end running in expected time, anyway, you solved one part of my problem by reminding me that this works as pass-by-reference, but I am still not sure if this is proper way of dealing with that. Does TS have any build-in magic keywords to access class context? – Bartłomiej Sobieszek Dec 27 '16 at 01:35
  • TypeScript is simply javascript. There is no new magic keywords (words that literally change how javascript works), *this* always existed in javacsript, thats why you can use it in typescript. – Erik Philips Dec 27 '16 at 01:37

2 Answers2

3

There's no duplicated objects in your code. _this is just a reference to this. In fact, you can avoid _this using an arrow function or binding your function.

bind:

class GoogleMapsClass {
    public map;

    constructor(selector) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState == 4) {
                this.map = xhttp.responseText;
            }
        }.bind(this);
        xhttp.open("GET", "/test.php", false);
        xhttp.send();
    }
}

Arrow function:

class GoogleMapsClass {
        public map;

        constructor(selector) {
            var xhttp = new XMLHttpRequest();
            xhttp.onreadystatechange = () => {
                if (xhttp.readyState == 4) {
                    this.map = xhttp.responseText;
                }
            }
            xhttp.open("GET", "/test.php", false);
            xhttp.send();
        }
    }
Andrés Andrade
  • 2,213
  • 2
  • 18
  • 23
  • Won't arrow function fail in this case? There's two `this` in the code. One is the GoogleMapsClass object which was aliased to `_this` and one is the global object on which the `this.readyState` check is done. – slebetman Dec 27 '16 at 02:40
  • @slebetman Nice catch! I've edited my answer. Thanks – Andrés Andrade Dec 27 '16 at 03:07
0

I don't see anywhere in your code where you are duplicating objects.

$(document).ready(function(){
  
  var first = {};
  var second = first;
  second.value = "whatever";

  $('#test1').text(first.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test1"></div>

In the example above first and second point to the same object, there is no duplication of objects. I set a value on second and can read it from first because they are literally the same object.

What is the most correct way to handle context switching?

Many people do one of the following lines of code:

var _this = this;
var $this = this;
var self = this;

They all work, and there is no tangible performance or memory issues doing this.

Erik Philips
  • 53,428
  • 11
  • 128
  • 150