۲۵ ژوئیه ۲۰۲۲

توابع ابتدایی

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

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

بیایید به تفاوت‌های اصلی بین یک شئ و داده‌های ابتدایی بنگریم.

یک داده ابتدایی

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

یک شئ

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

یکی از بهترین خصوصیات اشیا این است که ما میتوانیم یک تابع را به عنوان مشخصه‌های خودش ذخیره کنیم.

let john = {
  name: "John",
  sayHi: function() {
    alert("Hi buddy!");
  }
};

john.sayHi(); // Hi buddy!

ما اینجا یک شئ ساختیم john با تابع sayHi.

تعداد زیادی اشیا از قبل تعریف شده در حال حاضر وجود دارد مثل آنهایی که با تاریخ، خطاها، المان‌های html و غیره کار میکنند که توابع و مشخصه‌های متفاتی هم دارند.

اما این خواص هزینه‌ای دارند!

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

یک داده‌ ابتدایی به عنوان یک شئ

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

  • مقدارهای اصلی باید تا حد امکان سریع و سبک باشند.

راه حال، اندکی عجیب به نظر میرسد:

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

دربرگیرنده‌های اشیا برای هر نوع ابتدایی مختلف هستند به نام‌های: ‍رشته حروف،‍ عدد، متغیر بولی و نماد. بنابراین آنها مجموعه‌ای از توابع مختلفی را فراهم میسازند.

برای مثال، تابع str.toUpperCase() که خروجی آن، حروف کاپیتال شده رشته حرف ورودی میباشد.

روش کار به صورت زیر است:

let str = "Hello";

alert( str.toUpperCase() ); // HELLO

ساده است، نه؟! ببینیم در درون str.toUpperCase() چه اتفاقی می‌افتد:

۱. رشته حرف str یک داده ابتدایی‌ست. پس در هنگام دسترسی به مشخصه‌ش، یک شی اختصاصی ساخته میشود که مقدار رشته حرف را میداند و توابع مفیدی مثل toUpperCase() دارد.

۲. این تابع اجرا میشود و یک رشته حرف جدید را خروجی میدهد. (نشان داده شده توسط alert .)

۳. شی اختصاصی نابود میشود و داده ابتدایی str را تنها میگذارد.

بنابراین داده‌های ابتدایی میتوانند توابع را فراهم سازند و در عین حال سبک‌وزن هم میمانند.

موتور جاوااسکریپت این پردازه را به شدت بهینه میسازد به طوریکه حتی ممکن است ساخته شدن شئ اضافی را انجام ندهد. اما هنوز بایستی به مشخصات پایبند باشد و مثل ساخته شدن یک شئ رفتار کند.

یک عدد هم توابع خودش را دارد، به عنوان مثلا، toFixed(n) عدد را با دقت خواسته شده گرد میکند:

let n = 1.23456;

alert( n.toFixed(2) ); // 1.23

در بخش‌های اعداد and رشته‌ها توابع خاص بیشتری خواهیم دید.

Constructors رشته حرف/عدد/متغیر بولی فقط برای استفاده‌ی درونی هستند

بعضی از زبان‌های برنامه‌نویسی مثل جاوا به ما اجازه ساختن دربرگیرنده اشیا برای داده‌های ابتدایی را میدهند که با کدی مثل new Number(1) یا new Boolean(false) کار میکنند.

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

به عنوان مثال:

alert( typeof 1 ); // "number"

alert( typeof new Number(1) ); // "object"!

اما چون صفر یک شئ است، پیغام زیر ظاهر خواهد شد:

let zero = new Number(0);

if (zero) { // zero is true, because it's an object
  alert( "zero is truthy?!?" );
}

از سویی دیگر، استفاده از توابع مشابه String/Number/Boolean بدون new، کامل درست و مفید است. آنها یک مقدار را به نوع مربوطه‌شان تبدیل میکنند: یک رشته حرف، یک عدد یا یک متغیر بولی (داده ابتدایی).

برای مثال، این کاملا صحیح است:

let num = Number("123"); // convert a string to number
.هیچ/تعریف نشده هیچ تابعی ندارند

داده‌های ابتدایی خاص هیچ و تعریف نشده، استثنا هستند. آنها هیچ دربرگیرنده اشیا خاصی ندارند و هیچ تابعی را فراهم نمیسازند. به زبانی دیگر، آنها ابتدایی ترین ها هستند.

یک تلاش برای دسترسی به مشخصه چنین مقداری، خطای ذیل را میدهد:

alert(null.test); // error

خلاصه

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

تمارین

اهمیت: 5

کد زیر را در نظر بگیرید:

let str = "Hello";

str.test = 5;

alert(str.test);

فکر میکنید چطور کار خواهد کرد؟ چه چیزی نمایش داده خواهد شد؟

اجرا کنید:

let str = "Hello";

str.test = 5; // (*)

alert(str.test);

ممکن است دو نوع جواب وجود داشته باشد: ۱. تعریف نشده ۲. یک خطا

چرا؟ بگذارید دوباره ببینیم چه اتفاقی در خط (*) می‌افتد:

۱. وفتی یک مشخصه‌ی str در دسترس قرار می‌گیرد، یک دربرگیرنده شئ ساخته می‌شود.

۲. عملوند به همراه مشخصه می‌آید. بنابراین شئ مشخصه test را هم دارد.

۳. عملیات تمام می‌شود و دربرگیرنده شئ ناپدید میشود.

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

بعضی از مرورگرها حتی ممکن است تصمیم بگیرند که برنامه‌نویس را محدود کنند و اجازه‌ی دسترسی به تخصیص مشخصه‌ها به داده‌های ابتدایی ندهند. به همین علت است که ما میتوانیم همچنین در عمل، خطا در خط (*) را ببینیم. البته کمی دور از انتظار است.

این مثال به وضوح نشان میدهد که داده‌های ابتدایی، شئ نیستند.

آنها نمیتوانند اطلاعات را ذخیره کنند.

تمامی عملوند‌های توابع/مشخصه‌‌ها با کمک اشیا موقتی انجام می‌شود.

نقشه آموزش