چرا مبدل تایپاسکریپت متغیرها را بالا نمیبرد؟
من میدانم که هر دو ES6 و TypeScript از محدودهبندی سطح بلوک پشتیبانی میکنند، اما هنگام هدفگیری ES3 و ES5 خروجی باید محدودهبندی سطح تابع باشد. فکر میکنم باید یک منطق پشت این موضوع باشد که چرا TypeScript متغیرها را بالا نمیبرد... و من با مشکلی مواجه نیستم، بیشتر کنجکاوم که چرا متغیرها را بالا نمیبرد.
برای مثال، با توجه به TypeScript زیر:
function seed(length: number, multiplier: number): number[] {
let result: number[] = [];
for(let i: number = 0; i < length; i++) {
let n: number = i * multiplier;
result.push(n);
}
return result;
}
ترنسپایلر خروجی میدهد:
function seed(length, multiplier) {
var result = [];
for (var i = 0; i < length; i++) {
var n = i * multiplier;
result.push(n);
}
return result;
}
نتیجهای که من انتظار داشتم، نتیجهای بود که اعلانهای متغیر به بالای تابع منتقل شده باشند. چیزی شبیه به این:
function seed(length, multiplier) {
var
i, n,
result = [];
for (i = 0; i < length; i++) {
n = i * multiplier;
result.push(n);
}
return result;
}
هر بینشی بسیار قدردانی میشود. متشکرم!
پاسخ شماره ۱
این به این دلیل است که کامپایلر کد را بر اساس یک استاندارد کدنویسی تولید نمیکند. آن تلاش میکند که هر چه بیشتر به ورودی اصلی نزدیک باشد.
توجه داشته باشید که متغیرهای var به هر حال در پشت صحنه بالا برده میشوند (hoisting متغیر). در این مورد نیازی نیست که کامپایلر TypeScript ورودی را تغییر دهد و انجام این کار به طور غیرضروری پیچیدگی آن را افزایش میدهد.
پاسخ شماره ۲
من فکر میکنم باید یک منطق پشت اینکه چرا تایپاسکریپت متغیرها را به بالا نمیبرد وجود داشته باشد.. و من با مشکل روبهرو نیستم، بیشتر فقط کنجکاو هستم که چرا متغیرها را به بالا نمیبرد.
دقیقاً همین. چون مشکلی وجود ندارد، چرا زحمت بالا بردن را متحمل شویم؟
همچنین در مورد let، در واقع اشتباه خواهد بود اگر آن را به روشی که نشان دادید بالا بکشید.
منطقه مرده زمانی
اولین نکته این است که متغیرهای let نمیتوانند قبل از اعلام استفاده شوند، مانند متغیرهای var. با var شما مقدار undefined دریافت میکردید. با let به دلیل منطقه مرده زمانی، یک ReferenceError دریافت میکنید. خوشبختانه TypeScript در هر صورت به شما یک خطای زمان کامپایل میدهد تا در زمان اجرا با این مشکل مواجه نشوید :
console.log(a); // Error: Block scoped variable used before declaration
let a = 123;
دامنهبندی بلوکی
متغیرهای let که در یک for اعلام میشوند فقط در حلقهٔ for قابل دسترسی هستند. این به این دلیل است که آنها محدوده بلوکی دارند و نه محدوده تابعی. اطلاعات بیشتر در این مورد
دوباره، TypeScript در زمان کامپایل، اگر let را نادرست استفاده کنید، به شما خطا میدهد (به جای اینکه در زمان اجرا به آن برخورد کنید):
for(let i: number = 0; i < 10; i++) {
}
console.log(i); // Error: no variable i in scope
امیدوارم مفید باشد 🌹
