Pull to refresh

TypeScript одна маленькая тонкость: разница между function и =>

Доброго дня всему Хабрасообществу. Сегодня наткнулся на одну очень интересную граблю особенность TypeScript.
Я, как порядочный JS программист, привык, что у функции вложенной в функцию свой scope (не знаю как по-русски), т.е. объект, на который ссылается this, но в TS это не всегда так.

Далее небольшой совершенно бесполезный демонстрационный пример:

class MyClass {
    constructor()
    {
        this.on(
            window, // scope для callback'а
            () => { console.log(this['location']); } // callback
        );
    }
    private on(scope, callback){
        callback.call(scope); // не бейте, так надо
    }
}
var cls = new MyClass();


Если кому лень читать, то тут написано следующее: выполнить «console.log(this['location']);», при чем this указывает должен указывать на window.
После компидяции и выполнения мы получаем в консоли «undefined» (даже два), почему так? Давайте залезем в JS исходник:

var MyClass = (function () {
    function MyClass() {
        var _this = this;
        this.on(window, function () {
            console.log(_this['location']);
        });
    }
    MyClass.prototype.on = function (scope, callback) {
        callback.call(scope);
    };
    return MyClass;
})();
var cls = new MyClass();

Обратите внимание на «console.log(_this['location']);». Компилятор фактически подменил scope! Как сделать так чтоб он его не подменял? Нужно вместо

() => { console.log(this['location']); }

написать

function(){ console.log(this['location']); }

Итак, мотаем на ус: если используем => то this равен this'у родителя (ч/з замыкание), если function, то все как в vanilla js.
В простых методах (не конструкторе) поведение сохраняется.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.