مفهوم تابع در تایپ اسکریپت — به زبان ساده

۸۷ بازدید
آخرین به‌روزرسانی: ۰۱ مهر ۱۴۰۲
زمان مطالعه: ۸ دقیقه
مفهوم تابع در تایپ اسکریپت — به زبان ساده

هدف این مقاله آن است که قابلیت‌های زبان تایپ اسکریپت را برای نوشتن تابع‌های با قابلیت نگهداری و استفاده مجدد نشان دهد. تایپ اسکریپت به توسعه‌دهندگان جاوا اسکریپت امکان می‌دهد که از ابزارها و رویه‌های توسعه با بهره‌وری بالا مانند بررسی استاتیک و ریفکتور کد در زمان برنامه‌نویسی اپلیکیشن‌های جاوا اسکریپت بهره بگیرند.

تابع‌ها بلوک‌های تشکیل‌دهنده بنیادی یک اپلیکیشن محسوب می‌شوند. تابع عملی است که یک رفتار خاص مانند لاگین کردن کاربر، نمایش فهرستی از آیتم‌ها، درخواست داده از سرور و مواردی از این دست را اجرا می‌کند. این اعمال با همدیگر یک سیستم تشکیل می‌دهند که وظایف مختلف را حل می‌کنند.

تابع‌ها در ریاضیات به صورت شیئی توصیف می‌شوند که در زمان ارائه یک ورودی، یک خروجی عرضه می‌کنند. با این حال در برنامه‌نویسی دو نوع تابع وجود دارد، تابعی که مقداری بازگشت می‌دهد و تابعی که چیزی بازگشت نمی‌دهد. برای نمونه اگر لازم باشد چیزی مانند مجموع دو عدد بازگشت یابد، باید مقدار کل را بازگشت دهیم. اما در صورتی که لازم باشد یک پیام را در کنسول نمایش دهیم، نوع بازگشتی ضرورتی ندارد.

1. تایپ اسکریپت چیست؟

شاید از خود بپرسید چه نیازی به نوع‌بندی داده‌ها داریم. تصور کنید ایمیلی بدون موضوع به شخصی ارسال می‌کنیم. اینک وی برای درک ایمیل باید آن را باز کرده و بخواند. این کار موجب هدر رفت زمان می‌شود و هزینه سربار ایجاد می‌کند در حالی که اگر موضوع ایمیل مشخص می‌شد، گیرنده می‌توانست به سهولت از این زمان هدر رفته جلوگیری کند.

این مشکل در مورد یک ایمیل چندان برجسته نیست، در حالی که وقتی هزاران ایمیل دریافت شود، مقدار زمان و منابع مورد نیاز برای درک محتوای آن‌ها بسیار زیاد خواهد بود.

همین مفهوم در مورد توسعه‌دهندگان در زمان یادگیری کدنویسی نیز صدق می‌کند. فرض کنید کلاس‌ها، تابع‌ها، اشیا، متدها، متغیرها و موارد زیادی از این دست بدون نوع‌بندی دارید. هیچ برچسبی وجود ندارد که داده‌ها را توصیف کند. تنها روش برای درک آن این است که توسعه‌دهنده با کدنویس تماس بگیرد، سورس کد را باز کند، یا روی آن تست اجرا نماید. بدیهی است که این رویکردی مناسب برای برنامه‌نویسی کارآمد محسوب نمی‌شود.

تایپ اسکریپت به پیشگیری از چنین سناریوهایی در مورد نوع‌بندی کمک می‌کند و توسعه‌دهنده مجبور نیست حدس بزند یا پیش‌بینی کند که یک شیء چه مشخصه‌هایی دارد.

تفاوت کدی که بین جاوا اسکریپت و تایپ اسکریپت وجود دارد در همین نوع‌بندی است. در مثال ساده زیر می‌بینید که اگر یک متن را به یک عدد انتساب دهیم، چه اتفاقی می‌افتد:

1// JavaScript
2let age = 4; 
3age = 'Elon Musk'; // Works fine
4
5// TypeScript
6let age: number = 10;
7age = 'Bob Marley'; // Type error

2. تایپ اسکریپت جایگزین جاوا اسکریپت نمی‌شود

درک این که تایپ اسکریپت یک ابرمجموعه جاوا اسکریپت است حائز اهمیت بالایی است. تایپ اسکریپت جایگزین جاوا اسکریپت نمی‌شود، بلکه آن را بسط می‌دهد. بدین ترتیب امکان نوع‌بندی داده‌ها ایجاد شده و قابلیت‌های فراوان دیگری ارائه می‌شود که به توسعه‌دهندگان کمک می‌کند تا تابع‌های تمیز، خوانا و قابل نگهداری که قابلیت مقیاس‌بندی دارند بنویسند.

جاوا اسکریپت یک زبان دینامیک است که در آن نوع‌ها از سوی موتور مرورگر (run-time) تعریف می‌شوند، اما در تایپ اسکریپت توسعه‌دهنده این انعطاف را دارد که نوع‌ها را پیش‌تر و در زمان کدنویسی تعریف کند. این بدان معنی است که کامپایلر می‌تواند اغلب باگ‌ها را پیش از ورود به مرحله production شناسایی کند.

برای نمونه، اگر توسعه‌دهنده کدی مانند زیر بنویسد:

1const name = 'Bob Marley'

موتور جاوا اسکریپت با خواندن داده‌ها نوع داده را تشخیص می‌دهد که در این مورد مقدار Bob Marley از نوع string است. با این که نوع متغیر name مشخص شده است، اما همچنان افراد می‌توانند مقدار عددی یا شیء و تابع نیز به آن انتساب دهند و هیچ خطایی دریافت نخواهد شد. افراد زیادی استدلال می‌کنند که این رفتار عجیب است، در حالی که برخی دیگر نیز می‌گویند که این مسئله با ماهیت دینامیک جاوا اسکریپت همسو است.

3. آیا واقعاً به نوع‌بندی نیاز داریم؟

هنگامی که از تابع‌های موجود در اپلیکیشن‌های کوچک و بزرگ استفاده می‌کنیم، سؤالات اغلب به این صورت هستند که این تابع چه آرگومان‌هایی می‌پذیرد و چه چیزی بازگشت می‌دهد؟

تایپ اسکریپت از طریق تعریف نوع‌بندی برای آرگومان‌ها (ورودی) و گزاره بازگشتی (خروجی) به روشی شهودی، چنین سؤالاتی را رفع می‌کند. بدین ترتیب سردرگمی و سوءتفاهم از مسائل رفع می‌شود. توسعه‌دهنده می‌تواند به سرعت بداند که چطور می‌تواند با یک تابع تعامل یافته یا از آن استفاده مجدد بکند.

نکته: هدف تایپ اسکریپت محدودسازی توسعه‌دهنده به نوشتن کد کمتر جاوا اسکریپت نیست، بلکه می‌خواهد به درک این موارد کمک کند.

در ادامه دو نمونه کد می‌بینید. نمونه کد اول تابعی را نمایش می‌دهد که نوع‌بندی ندارد (در جاوا اسکریپت معمول است) و دومی دارای نوع‌بندی است (در تایپ اسکریپت معمول است).

مثال اول: جاوا اسکریپت

1// Add two numbers
2function add(a, b) {
3    return a + b;
4}
5
6// Store result
7const result = add(10,'hello');
8
9// Print out
10console.log(result); // Output: 10hello

چنان که در نمونه کد فوق می‌بینید، تابع دو آرگومان می‌گیرد و نتیجه‌ای بازگشت می‌دهد که 10hello است. اکنون اگر کد را اجرا کنید، هیچ خطایی دریافت نمی‌شود، زیرا کد آن چه را که انتظار می‌رود، اجرا می‌کند و دو مقدار را صرفنظر از نوع اضافه می‌کند.

در جاوا اسکریپت علامت + به معنی الحاق است که به صورت رایجی برای ترکیب کردن متن با مقادیر به صورت 'Hi' + firstName استفاده می‌شود. این نوع از رفتار چیزی نیست که دوست داشت باشیم در جای جای اپلیکیشن ببینیم.

نکته: فقدان نوع‌بندی امکان کار بهینه را از توسعه‌دهنده گرفته است و زمانی که توسعه‌دهنده بخواهد به صورت دستی کد و مستندات را بررسی کرده و از طرز کار آن‌ها سر دربیاورد، زمان زیادی صرف می‌شود، در حالی که این مسئله در تایپ اسکریپت بسیار سریع انجام می‌شود.

مثال دوم: تایپ اسکریپت

1// Add two numbers
2function add(a: number, b: number) {
3    return a + b;
4}
5
6// Store result
7const result = add(10,'hello'); // A type-error is shown in code
8
9// Print out
10console.log(result); // Output: type error, it expects a number but got a string.

اکنون اگر یک عدد و یک رشته را مانند قبل به تابع ارسال کنیم، یک خطای نوع بازگشت می‌یابد، زیرا این تابع تنها آرگومان‌هایی از نوع number می‌پذیرد. این بدان معنی است که باگ‌های برنامه کاهش می‌یابند و اپلیکیشن امنی داریم که کد آن گویا است.

نکته: هدف این نیست که همه چیز را نوع‌بندی کنیم، ما همچنان از ماهیت دینامیک جاوا اسکریپت بهره می‌گیریم، اما باید مطمئن شویم که تابع‌ها یا کلاس‌ها به صورت صحیحی از سوی توسعه‌دهندگان استفاده می‌شوند.

4. پارامترهای نوع‌بندی شده

در تایپ اسکریپت، تعداد آرگومان‌های ارسالی به یک تابع باید برابر با تعداد پارامترهایی باشد که تابع می‌پذیرد. اما در جاوا اسکریپت یک تابع می‌تواند هر تعداد آرگومان که ارسال می‌شود را بپذیرد:

1// Function accepts two parameters
2function getCar(name: string, year: number) {
3    return { name, year };
4}
5
6getCar('Mercedes Benz CLA200', 2020, 'Blue', 'Automatic'); // expected 2 arguments, but got 4.
7getCar('Mercedes Benz CLA200'); // expected 2 arguments, but got 1.
8getCar('Mercedes Benz CLA200', 2020); // the compiler is happy

5. پارامترهای اختیاری

پارامترهای تابع در تایپ اسکریپت به صورت پیش‌فرض همچون جاوا اسکریپت «اختیاری» (optional) نیستند. پارامترهای اختیاری در مواردی که مقدار در یک زمان موجود نباشد، عالی هستند:

1function addCar(name: string, year: number, sold?: boolean) {
2    return { name, year, sold };
3}
4
5addCar('Tesla Model 3', 2019) // { ..., sold: undefined }
6addCar('Tesla Model 3', 2019, true) // { ..., sold: true }

چنان که می‌بینید با افزودن یک علامت سؤال (؟) به انتهای پارامتر، آن را به صورت اختیاری در می‌آوریم.

نکته: یک پارامتر اختیاری باید پس از پارامتر الزامی تعریف شود، در غیر این صورت پیام خطایی به صورت زیر ظاهر می‌شود:

required parameter cannot follow an optional parameter.

اگر هیچ آرگومانی ارسال نشده باشد، مقدار به صورت تعریف‌نشده تعیین می‌شود. اما اگر بخواهیم یک مقدار پیش‌فرض تعیین کنیم، آیا می‌توانیم مقدار sold را به صورت پیش‌فرض هر زمان که خودروی جدیدی اضافه می‌کنیم تعیین نماییم؟ برای رفع این مشکل به صورت زیر عمل می‌کنیم:

1function addCar(name: string, year: number, sold = false) {
2    return { name, year, sold };
3}
4
5addCar('BMi3', 2019) // { ... sold: false } <-- Default value set
6addCar('BMW i3', 2019, true) // { ... sold: true }

هر بار که خودروی جدیدی ایجاد می‌کنیم، متغیر sold به صورت پیش‌فرض روی مقدار false تعیین می‌شود. توجه کنید که ما از علامت پارامتر اختیاری به صورت boolean: sold استفاده می‌کنیم، زیرا تایپ اسکریپت نوع‌ها را به صورت خودکار مدیریت می‌کند.

6. پارامترهای Overload

برخی اوقات یک تابع می‌خواهیم که تنها یک کار انجام دهد و در برخی موارد دیگر می‌خواهیم تابع بر مبنای آرگومان‌هایی که ارسال می‌کنیم (پارامترهای overload) کارهای اضافی انجام دهد. این مفهوم که می‌توانیم هنگام کار با تابع‌ها، لایه‌های انتزاعی با رفتارهای مختلف ایجاد می‌کنیم، مفید است. در مثال زیر از پارامترهای overload استفاده کرده‌ایم:

1// Create overloads
2function runEngines(engine: { engine1: boolean; engine2: boolean });
3function runEngines(engines: number);
4function runEngines(engines: boolean);
5function runEngines(x): any {
6    // If argument is number
7    if (typeof x === "number") {
8        console.log(`Run all ${x}`);
9    }
10    // If argument is an object
11    if (typeof x === "object") {
12        console.log(`Run eng1: ${x.engine1}, eng2: ${x.engine2}`);
13    }
14    // If argument is a boolean
15    if (typeof x === "boolean") {
16        let msg = x ? "Start all engines" : "Stop all engines";
17        console.log(msg);
18    }
19}
20// Invoke function
21runEngines({ engine1: true, engine2: false }); // Output: Run eng1: true, eng2: false
22runEngines(4); // Output: 4
23runEngines(true); // Output Start all engines

چنان که در مثال فوق می‌بینیم، تابع ()runEngines از کلیدواژه typeof برای بررسی نوع آرگومان و تعریف عملیاتی که باید انجام شود بهره می‌گیرد. توجه کنید که تابع function runEngines(x): any باید آخر از همه تعریف شده باشد، زیرا یک تابع سراسری است که همه احتمالات تعریف شده در تابع فوق را نمایش می‌دهد.

این رویکرد توصیه نمی‌شود، زیرا یک تابع با چند رفتار تعریف می‌شود که موجب دشواری نگهداری و استفاده مجدد از کد می‌شود، یک رویکرد ممکن می‌تواند این باشد که رفتار را به تابع‌های جداگانه‌ای تقسیم کنیم که در برنامه‌نویسی رویه‌ای مناسب تلقی می‌شود. با این حال در برخی موارد چنین رویکردی ممکن است ضروری باشد؛ در نهایت همه چیز به الزامات برنامه بستگی دارد.

7. مزیت‌های یادگیری تایپ اسکریپت

نوشتن تابع در جاوا اسکریپت به صورت کلی کاری آسان است، اما زمانی که بر حجم خطوط کد و اعضای تیم اضافه می‌شود، نگهداری و استفاده مجدد از کد دشوار می‌شود، چون نوع‌بندی وجود ندارد.

اگر با نوع‌بندی که یکی از قابلیت‌های اصلی تایپ اسکریپت است آشنا نیستید، ضروری است که نوع داده‌هایی که استفاده می‌شوند را به صورت number ،string یا یک شیء تعریف کنید.

اغلب توسعه‌دهندگان با کتابخانه‌های جاوا اسکریپت (پکیج‌های NPM) آشنا هستند و به طور مکرر در موقعیت‌هایی قرار می‌گیرند که برای درک احتمالات یک تابع مانند این که چه متدها یا مشخصه‌هایی موجود هستند، به مقدار زیادی مطالعه نیاز دارند.

تایپ اسکریپت به توسعه‌دهندگان کمک می‌کند که به سرعت انعطاف‌پذیری تابع‌ها، اشیا، کلاس‌ها و متغیرها را به جای بررسی سورس کد درک کنند و به این ترتیب در زمان و منابع صرفه‌جویی می‌شود.

تایپ اسکریپت یک تجربه توسعه عالی نیز از طریق پشتیبانی از IDE بهبود یافته عرضه می‌کند. یک IDE مانند ویژوال استودیو به توسعه‌دهندگان کمک می‌کند که به سهولت خطاهای کامپایل را تشخیص دهند، اقدام به ریفکتور کد بکنند و انعطاف‌پذیری یک تابع را درک نمایند. بدین ترتیب توسعه‌دهندگانی مانند من و شما می‌توانیم وقت بیشتری روی کدنویسی صرف کنیم و کمتر به دیباگ بپردازیم.

سخن پایانی

تایپ اسکریپت جایگزینی برای جاوا اسکریپت نیست، بلکه صرفاً زبانی است که به توسعه‌دهندگان کمک می‌کند تا کد با قابلیت نگهداری و استفاده مجدد بیشتر بسازند. تایپ اسکریپت نوع‌بندی را الزام نمی‌کند، بلکه آن را پیشنهاد می‌کند. بدین ترتیب تجربه کدنویسی به سطحی کاملاً جدید انتقال می‌یابد که در آن فرد می‌تواند مستقیماً مرزها و داده‌هایی که تابع می‌پذیرد را ببیند.

در نهایت تایپ اسکریپت در مقایسه با جاوا اسکریپت امکان افزایش چشمگیری در بهره‌وری می‌دهد. به طور خلاصه تایپ اسکریپت موجب نمی‌شود که توسعه‌دهنده در طی یک شب ترقی چشمگیری بکند، چون هیچ زبانی چنین قابلیتی ندارد، اما آن چه تایپ اسکریپت را خاص ساخته است، تعداد قابلیت‌ها و آن انعطاف‌پذیری است که به توسعه‌دهندگان کمک می‌کند کد با کیفیت بالا و پایدار تولید کنند.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۱ نفر
آیا این مطلب برای شما مفید بود؟
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.
منابع:
better-programming
نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *