Typescript "this" внутри метода класса
Я знаю, что это, вероятно, болезненно простой, но у меня есть трудное время, обернув мою голову вокруг него.
class Main
{
constructor()
{
requestAnimationFrame(this.update); //fine
}
update(): void
{
requestAnimationFrame(this.update); //error, because this is window
}
}
похоже, что мне нужен прокси, поэтому давайте скажем, используя Jquery
class Main
{
constructor()
{
this.updateProxy = $.proxy(this.update, this);
requestAnimationFrame(this.updateProxy); //fine
}
updateProxy: () => void
update(): void
{
requestAnimationFrame(this.updateProxy); //fine
}
}
но исходя из фона Actionscript 3, я не совсем уверен, что здесь происходит. Извините, я не уверен, где начинается Javascript и заканчивается TypeScript.
updateProxy: () => void
а также, я не уверен, что я делаю это правильно. Последнее, чего я хочу-это большая часть моего класса имеет функцию a (), к которой нужно обращаться с помощью aProxy()
как я чувствую, что я пишу то же самое дважды? Это нормально?
5 ответов:
если вы хотите
this
захватил способ TypeScript сделать это с помощью функций стрелки. Цитируя Андерса:The
this
в функции стрелки лексически ограниченвот как я хотел бы использовать это в своих интересах:
class test{ // Use arrow functions func1=(arg:string)=>{ return arg+" yeah" + this.prop; } func2=(arg:number)=>{ return arg+10 + this.prop; } // some property on this prop = 10; }
посмотреть это в TypeScript Playground
вы можете видеть, что в сгенерированном JavaScript
this
плен за пределами функции звоните:var _this = this; this.prop = 10; this.func1 = function (arg) { return arg + " yeah" + _this.prop; };
так
this
значение внутри вызова функции (которая может бытьwindow
) не будет использоваться.чтобы узнать больше: "понимание
this
in TypeScript "(4:05) – YouTube
Если вы пишете свои методы, как это, " это " будет рассматриваться так, как вы ожидаете.
class Main { constructor() { requestAnimationFrame(() => this.update()); } update(): void { requestAnimationFrame(() => this.update()); } }
другой вариант-привязать " это " к вызову функции:
class Main { constructor() { requestAnimationFrame(this.update.bind(this)); } update(): void { requestAnimationFrame(this.update.bind(this)); } }
проблема возникает, когда вы передаете функцию в качестве обратного вызова. К моменту выполнения обратного вызова значение "this" может быть изменено на окно, элемент управления, вызывающий обратный вызов, или что-то еще.
убедитесь, что вы всегда используете лямбда-выражение в точке передачи ссылки на вызываемую функцию. Например
public addFile(file) { this.files.push(file); } //Not like this someObject.doSomething(addFile); //but instead, like this someObject.doSomething( (file) => addFile(file) );
это компилируется к чему-то вроде
this.addFile(file) { this.files.push(file); } var _this = this; someObject.doSomething(_this.addFile);
потому что функция addFile вызывается на a конкретная ссылка на объект (_this) он не использует "это" вызывающего, но вместо этого значение _this.
см. страницу 72 спецификации языка машинописи https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true
Выражения Функции Стрелка
пример
class Messenger { message = "Hello World"; start() { setTimeout(() => alert(this.message), 3000); } }; var messenger = new Messenger(); messenger.start();
использование выражения функции стрелки заставляет обратный вызов иметь то же самое, что и окружающий метод "старт". Написание обратного вызова в качестве стандартного выражения функции он становится необходимо вручную организуйте доступ к окружающему этому, например, скопировав его в локальная переменная:
это фактический сгенерированный Javascript:
class Messenger { message = "Hello World"; start() { var _this = this; setTimeout(function() { alert(_this.message); }, 3000); } };
короче, ключевое слово this всегда ссылается на объект, который вызвал функцию.
в Javascript, поскольку функции - это просто переменные, вы можете передавать их.
пример:
var x = { localvar: 5, test: function(){ alert(this.localvar); } }; x.test() // outputs 5 var y; y.somemethod = x.test; // assign the function test from x to the 'property' somemethod on y y.test(); // outputs undefined, this now points to y and y has no localvar y.localvar = "super dooper string"; y.test(); // outputs super dooper string
когда вы делаете следующее с jQuery:
$.proxy(this.update, this);
то, что вы делаете, переопределяет этот контекст. За кулисами jQuery будет guive вам это:
$.proxy = function(fnc, scope){ return function(){ return fnc.apply(scope); // apply is a method on a function that calls that function with a given this value } };