TypeScript此范围在闭包内不起作用

时间:2018-03-09 15:03:38

标签: typescript scope this

我是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方法中的this.speedUp不指向汽车对象?

哪种方法可以解决?

3 个答案:

答案 0 :(得分:2)

使用箭头功能,该功能保留this

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

答案 1 :(得分:0)

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

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
    );
}

答案 2 :(得分:0)

您建议使用箭头符号:

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());

将编译为:

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
);

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

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

{{1}}