javascript - TypeScript: async fonksiyonlarda arguments anahtar kelimesi
Projelerimden birinde fark ettiğim şu garip davranışı göz önünde bulundurun:
async function hello() {
return arguments;
}
TypeScript'in derleme hedefi es3 veya es5 olarak ayarlandığında, yukarıdaki dosya aşağıdaki hata ile derlenemez:
error TS2522: The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method.
2 return arguments;
~~~~~~~~~
Ancak, daha yüksek bir derleme hedefi ile (ben es2017 ve esnexti test ettim) herhangi bir hata yok.
arguments anahtar kelimesi ile ilgili olarak, TypeScript derleme hedefi es3 veya es5 olarak ayarlandığında neden async fonksiyonlarda kullanılamıyor?
Birkaç not:
- Modern JavaScript'te çoğaltıldığında, bu fonksiyon bir istisna fırlatmaz
- Bu davranış yalnızca
asyncfonksiyonlarında çoğaltılabilir
Hipotezim
Promise’in es3 ve es5’te polyfill edilmesi gerektiğinden dolayı, polyfill’in arguments’ı destekleyemeyeceğini düşünüyorum çünkü bu, fonksiyon çağıranına bağımlıdır.
Daha fazla okuma: ES5.1 Spec § 10.6 Argümanlar Nesnesi
Cevap #1
Bunun nedeni Async fonksiyonlarının, jeneratörlerin temel polifill uygulanmasına dönüştürülmesidir; bu uygulama temelde fonksiyonunuzun gövdesini başka bir fonksiyonla sarmak için değiştirir, bu nedenle herhangi bir arguments kullanımı, hello'nun orijinal arguments değerine asla ulaşamaz, bunun yerine __generator olacaktır.
Bunun bir örneği aşağıdadır; burada hiçbir argüman almayan ve aşağıdakileri üreten hello vardır; fonksiyonun gövdesi başka bir fonksiyonla sarılmıştır.
async function hello() {
console.log(arguments);
} // becomes.....
function hello() {
return __awaiter(this, arguments, void 0, function () {
return __generator(this, function (_a) {
console.log(arguments);
return [2 /*return*/];
});
});
}
Tekrar etmek gerekirse, console.log(arguments) hello bağlamından __generator bağlamına taşındı, bu da onun beklediğiniz gibi davranmayacağı anlamına gelir. Eğer modern tarayıcıları (IE dışı) hedefliyorsanız, derleme hedefinizi ES6+ olarak ayarlayabilirsiniz; bu durumda bu kısıtlama kaldırılacaktır.
Cevap #2
Sadece spread operatörünü kullan
hello(...args: any[])
şimdi geçirilen argümanların bir dizisine sahipsiniz.
