javascript - Typescript _this'e yanlış referans


TypeScript'te String.Prototype için bazı özellikler tanımlamaya çalıştım:

Object.defineProperty(String.prototype, 'test', {
    value: () => {
        console.log("this is a test over text " + this);
    }
})

javaScript prototiplerinde, this metodu çağıran nesneyi ifade eder (bu durumda string değeri). Ancak dosyanın derlenmiş çıktısı şudur:

var _this = this;
Object.defineProperty(String.prototype, 'test', {
    value: function () {
        console.log("this is a test over text " + _this);
    }
});

TypeScript derleyicisi _this değişkenini ekler ve ona başvurur.

Bu bir hata mı yoksa benim uygulamamda bir sorun mu var?

Cevap #1

Bu bir hata mı yoksa benim uygulamamda bir sorun mu var?

Hayır, bu TypeScript'in ok fonksiyonlarının nasıl çalıştığıyla ilgilidir: Ok fonksiyonlarda, this, fonksiyonun çağrılma şekliyle değil, fonksiyonun oluşturulduğu bağlamdan miras alınır. (Ok fonksiyonlar ayrıca ES2015'te de vardır, en azından kısmen CoffeeScript'in "kalın ok" fonksiyonlarından esinlenmiştir; TypeScript'in tarihini ve bunun ES2015 ok fonksiyonları için ilham kaynağı olup olmadığını ya da tam tersini bilmiyorum.)

Yukarıdaki spec bağlantısından bir alıntı:

Bir fonksiyon ifadesi, yeni bir dinamik olarak bağlanmış this tanıtırken, bir ok fonksiyonu ifadesi, kapsayan bağlamının this değerini korur.

Ok fonksiyon ifadeleri, aksi takdirde genellikle tanımsız veya beklenmeyen bir this değerine sahip olan geri çağırmaları yazmak için özellikle kullanışlıdır.

Örnekte

class Messenger {  
    message = "Hello World";  
    start() {  
        setTimeout(() => alert(this.message), 3000);  
    }  
};

var messenger = new Messenger();  
messenger.start();

Bir ok fonksiyon ifadesinin kullanılması, callback'in etrafındaki 'start' yöntemi ile aynı this'e sahip olmasına neden olur.

Eğer this'in fonksiyonun nasıl çağrıldığına bağlı olmasını istiyorsanız, ok fonksiyonu kullanmayın, function kullanın:

Object.defineProperty(String.prototype, 'test', function() {
    console.log("this is a test over text " + this);
})

Ayrıca, Nils'in belirttiği gibi, Object.defineProperty'e üçüncü argümanın bir işlev değil, bir özellik tanımlayıcı olması gerektiğini unutmayın. Belki şunu demek istemiştiniz:

Object.defineProperty(String.prototype, 'test', {
    value: function() {
        console.log("this is a test over text " + this);
    }
});

TypeScript derleyicisi bunu hiç değiştirmez; "testing".test() çağrısı "this is a test of text testing" çıktısını verir:

Object.defineProperty(String.prototype, 'test', {
    value: function() {
        snippet.log("this is a test over text " + this);
    }
});
"testing".test();
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

İlgili makaleler