TypeScriptのthis指向問題

3460 ワード

Type ScriptはJavaScriptのスーパーセットで、主にタイプシステムとES 6のサポートを提供しています.Microsoftが開発し、コードはGitHubからオープンしています.
Type ScriptはJavaScriptのタイプのスーパーセットで、純粋なJavaScriptにコンパイルできます.コンパイルされたJavaScriptは、任意のブラウザで実行できます.TypeScriptコンパイルツールは、任意のサーバおよび任意のシステムで実行できます.TypeScriptはオープンソースです.
上の点を明らかにしてから、TypeScriptのthisが問題を指していることを見てみましょう.
JavaScriptのthisの指向
次に、TypeScriptのthisの指向性について例を挙げて説明します.
class demo{
    private str:string = "hello";
    public abc(){
        console.log( this.str );
    }
}

コンパイルされたjsファイルコードは次のとおりです.
var demo = /** @class */ (function () {
    function demo() {
        this.str = "hello";
    }
    demo.prototype.abc = function () {
        console.log(this.str);
    };
    return demo;
}());

このように生成されたJSファイルも難解ではない.JSコードをもう少し簡単に修正して、
var demo = (function () {
    function demo() {
        this.str = "hello";
    }
    demo.prototype.abc = function () {
        console.log(this.str);
    };
    return demo;
})();

var d = new demo();
d.abc();

これにより、「hello」文字の印刷が表示されます.もう一度修正します.
var demo = (function () {
    function demo() {
        this.str = "hello";
    }
    demo.prototype.abc = function () {
        console.log( this.str);
    };
    demo.prototype.doing = function(callback){
        callback();
    }
    return demo;
})();
var d = new demo();
d.abc();
d.doing(d.abc);

このとき、helloが出力され、undefinedが出力されます.これがJSにおける比較的困惑する役割ドメインの問題である.このような問題を避けるためには、次のような修正が必要です.
var demo = (function () {
    var that;
    function demo() {
        this.str = "hello";
        that = this;
    }
    demo.prototype.abc = function () {
        console.log( that.str);
    };
    demo.prototype.doing = function(callback){
        callback();
    }
    return demo;
})();
var d = new demo();
d.abc();
d.doing(d.abc);

TypeScriptはこの問題を回避するために、融通性のある解決策を提供しています.
class demo{
    private str:string = "hello";
    public abc(){
        console.log( this.str );
    }
    public doing(callback){
        callback();
    }
    public start(){
        this.doing(this.abc);
    }
}

上のコードは、コンパイルされたJSコードは以下の通りです.
var demo = /** @class */ (function () {
    function demo() {
        this.str = "hello";
    }
    demo.prototype.abc = function () {
        console.log(this.str);
    };
    demo.prototype.doing = function (callback) {
        callback();
    };
    demo.prototype.start = function () {
        this.doing(this.abc);
    };
    return demo;
}());

書き方を変えれば
class demo{
    private str:string = "hello";
    public abc(){
        console.log( this.str );
    }
    public doing(callback){
        callback();
    }
    public start(){
        this.doing(()=> this.abc());
    }
}

このときコンパイルされたJSコードは次のようになります.
var demo = /** @class */ (function () {
    function demo() {
        this.str = "hello";
    }
    demo.prototype.abc = function () {
        console.log(this.str);
    };
    demo.prototype.doing = function (callback) {
        callback();
    };
    demo.prototype.start = function () {
        var _this = this;
        this.doing(function () { return _this.abc(); });
    };
    return demo;
}());

TypeScriptは,この役割ドメインの問題を言語レベルにカプセル化し,「Arrow Function」と名付けた.