【问题标题】:TypeScript this scope don't working within a closureTypeScript 这个范围在闭包中不起作用
【发布时间】:2018-03-09 15:03:37
【问题描述】:

我是 TypeScript 的初学者。我认为 typescript 可以解决我在 JavaScript 中使用这个范围的所有问题,但似乎并非如此。 请看下面的示例代码:

class Car{
    private name : string;
    private velocity: number;
    constructor ( name:string){
        this.name = name;
        this.velocity = 0;
    }

    private speedUp (incrementer: number){
        this.velocity += incrementer;
    }

    public pressAccelerator (power: number){
        console.log(this); //here this is a Car object       
        setTimeout(
            function(){
                // here is a Timeout object - WTF!!! 
                // was't this typeScript?
                // what's up whit my "this" object scope?
                console.log(this);
                this.speedUp(power*1.34); //TypeError: this.speedUp is not a function              
            },    
            1000
        );
    }
    public getVelocity():number{
        return this.velocity;
    }
}

let myCar = new Car("Mercedes");
myCar.pressAccelerator(2);
console.log(myCar.getVelocity());

为什么this.speedUp方法中的this没有指向汽车对象?

哪种方法比较实用?

【问题讨论】:

  • this 在您的匿名函数中指的是函数本身。正如在一些答案中所说,使用箭头函数具有与您想要的匹配的不同行为。

标签: typescript scope this


【解决方案1】:

使用箭头函数,保留this:

public pressAccelerator (power: number){
    console.log(this); //here this is a Car object       
    setTimeout(
        () => {
            console.log(this);
            this.speedUp(power*1.34);
        },    
        1000
    );
}

【讨论】:

    【解决方案2】:

    你建议习惯箭头符号:

    class Car {
        private name : string;
        private velocity: number;
    
        constructor (name: string) {
            this.name = name;
            this.velocity = 0;
        }
    
        private speedUp = (incrementer: number): void => {
            console.log(this);
            this.velocity += incrementer;
        } 
    
        public pressAccelerator = (power: number): void => {
    
            console.log(this); //here this is a Car object       
            setTimeout(() => this.speedUp(power*1.34), 1000);
        }
        public getVelocity = (): number => {
            return this.velocity;
        }
    }
    
    let myCar = new Car("Mercedes");
    myCar.pressAccelerator(2);
    console.log(myCar.getVelocity());
    

    编译为:

    var Car = /** @class */ (function () {
        function Car(name) {
            var _this = this;
            this.speedUp = function (incrementer) {
                console.log(_this);
                _this.velocity += incrementer;
            };
            this.pressAccelerator = function (power) {
                console.log(_this); //here this is a Car object       
                setTimeout(function () { return _this.speedUp(power * 1.34); }, 1000);
            };
            this.getVelocity = function () {
                return _this.velocity;
            };
            this.name = name;
            this.velocity = 0;
        }
        return Car;
    }());
    var myCar = new Car("Mercedes");
    myCar.pressAccelerator(2);
    console.log(myCar.getVelocity());
    

    如您所见,打字稿将修复该闭包。你可以阅读更多here


    如果您在计时器回调中定义了一个具有范围的函数,则无法解决的问题:(非箭头函数)

    setTimeout(
        function(){
            // here is a Timeout object - WTF!!! 
            // was't this typeScript?
            // what's up whit my "this" object scope?
            console.log(this);
            this.speedUp(power*1.34); //TypeError: this.speedUp is not a function              
        },    
        1000
    );
    

    【讨论】:

      【解决方案3】:

      我不知道它是否优雅,但这有效:

      public pressAccelerator (power: number){
          console.log(this); //here this is a Car object   
          let self = this;
          setTimeout(
              function(){
                  console.log(self);
                  self.speedUp(power*1.34);
              },    
              1000
          );
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-22
        • 2013-10-31
        • 2020-08-24
        • 2011-12-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多