آموزش جاوا اسکریپت پیشرفته : شئ و پروتوتایپ آن
پروتوتایپها مکانیزمی هستند که اشیاء جاوا اسکریپت از طریق آنها ویژگیهایی را از یکدیگر به ارث میبرند. در این مقاله، ما توضیح میدهیم که پروتوتایپ چیست، چگونه زنجیرههای پروتوتایپ کار میکنند و چگونه میتوان یک پروتوتایپ برای یک شیء تنظیم کرد.
در کنسول مرورگر، سعی کنید یک شیء دستی ایجاد کنید:
این یک شیء با یک ویژگی داده، city، و یک متد، است. اگر نام شیء را به همراه یک نقطه در کنسول تایپ کنید، مانند ، کنسول لیستی از تمام ویژگیهای موجود برای این شیء را نمایش میدهد. خواهید دید که علاوه بر city و greet، ویژگیهای بسیار دیگری نیز وجود دارد!
سعی کنید به یکی از آنها دسترسی پیدا کنید:
این روش کار میکند (حتی اگر مشخص نباشد که چه کاری انجام میدهد).
این ویژگیهای اضافی چه هستند و از کجا میآیند؟
هر شیء در جاوا اسکریپت یک ویژگی داخلی دارد که به آن نمونه اولیه (prototype) میگویند. پروتوتایپ خودش یک شیء است، بنابراین پروتوتایپ، پروتوتایپ مخصوص به خود را خواهد داشت و چیزی را میسازد که به آن زنجیره پروتوتایپ میگویند. این زنجیره زمانی پایان مییابد که به پروتوتایپی میرسیم که برای پروتوتایپ خود مقدار null دارد.
ویژگی یک شیء که به پروتوتایپ آن اشاره میکند، پروتوتایپ نامیده نمیشود. نام آن استاندارد نیست، اما در عمل همه مرورگرها از استفاده میکنند. روش استاندارد برای دسترسی به پروتوتایپ یک شیء، متد است.
هنگامی که سعی میکنید به یک ویژگی از یک شیء دسترسی پیدا کنید: اگر ویژگی در خود شیء یافت نشود، پروتوتایپ برای آن ویژگی جستجو میشود. اگر ویژگی هنوز یافت نشود، پروتوتایپ پروتوتایپ جستجو میشود و به همین ترتیب ادامه مییابد تا زمانی که یا ویژگی پیدا شود یا به انتهای زنجیره برسد، که در این صورت undefined برگردانده میشود.
بنابراین وقتی را فراخوانی میکنیم، مرورگر:
به دنبال toString در myObject میگردد
آن را در آنجا پیدا نمیکند، بنابراین در پروتوتایپ myObject برای toString جستجو میکند
آن را در آنجا پیدا میکند و آن را فراخوانی میکند.
پروتوتایپ myObject چیست؟ برای فهمیدن آن، میتوانیم از تابع استفاده کنیم:
این شیء نام دارد و ابتداییترین پروتوتایپ است که همه اشیاء به طور پیشفرض دارند. پروتوتایپ نال است، بنابراین در انتهای زنجیره پروتوتایپ قرار دارد.
پروتوتایپ یک شیء همیشه نیست. این را امتحان کنید:
این کد یک شیء Date ایجاد میکند، سپس زنجیره prototype را پیمایش میکند و prototypeها را ثبت میکند. این به ما نشان میدهد که prototype مربوط به myDate یک شیء است و prototype مربوط به آن است.
در واقع، وقتی متدهای آشنایی مانند را فراخوانی میکنید، در واقع متدی را فراخوانی میکنید که روی تعریف شده است.
چه اتفاقی میافتد اگر یک ویژگی را در یک شیء تعریف کنید، در حالی که یک ویژگی با همان نام در پروتوتایپ شیء تعریف شده است؟ بیایید ببینیم:
با توجه به توضیحات زنجیره نمونه اولیه، این باید قابل پیشبینی باشد. وقتی را فراخوانی میکنیم، مرورگر ابتدا در myDate به دنبال یک ویژگی با آن نام میگردد و فقط در صورتی که myDate آن را تعریف نکرده باشد، پروتوتایپ را بررسی میکند. بنابراین وقتی را به myDate اضافه میکنیم، نسخه موجود در myDate فراخوانی میشود.
به این کار «سایهگذاری» ویژگی میگویند.
روشهای مختلفی برای تنظیم پروتوتایپ یک شیء در جاوا اسکریپت وجود دارد و در اینجا دو مورد از آنها را شرح خواهیم داد: و سازندهها.
متد یک شیء جدید ایجاد میکند و به شما امکان میدهد شیءای را مشخص کنید که به عنوان پروتوتایپ شیء جدید استفاده خواهد شد.
در اینجا مثالی آورده شده است:
در اینجا ما یک شیء personPrototype ایجاد میکنیم که دارای متد است. سپس از برای ایجاد یک شیء جدید با personPrototype به عنوان پروتوتایپ آن استفاده میکنیم. اکنون میتوانیم را روی شیء جدید فراخوانی کنیم و پروتوتایپ پیادهسازی آن را فراهم میکند.
با استفاده از سازنده constructor
در جاوا اسکریپت، همه توابع دارای یک ویژگی به نام prototype هستند. وقتی یک تابع را به عنوان سازنده فراخوانی میکنید، این ویژگی به عنوان پروتوتایپ شیء تازه ساخته شده تنظیم میشود (طبق قرارداد، در ویژگی به نام).
بنابراین اگر پروتوتایپ یک سازنده را تنظیم کنیم، میتوانیم مطمئن شویم که به همه اشیاء ایجاد شده با آن سازنده، آن پروتوتایپ داده میشود:
در اینجا موارد زیر را ایجاد میکنیم:
یک شیء personPrototype که دارای متد است
یک تابع سازنده که نام شخصی که قرار است ایجاد شود را مقداردهی اولیه میکند.
سپس متدهای تعریف شده در personPrototype را با استفاده از در ویژگی prototype تابع Person قرار میدهیم.
پس از این کد، اشیاء ایجاد شده با استفاده از به عنوان prototype خود را دریافت میکنند که به طور خودکار شامل متد greet است.
این همچنین توضیح میدهد که چرا قبلاً گفتیم که نمونه اولیه myDate، نام دارد: این ویژگی پروتوتایپ سازنده Date است.
اشیاء ایجاد شده با استفاده از سازنده Person در بالا دارای دو ویژگی هستند:
یک ویژگی name که در سازنده تنظیم شده است، بنابراین مستقیماً روی اشیاء Person ظاهر میشود.
یک متد که در پروتوتایپ تنظیم شده است.
مشاهده این الگو که در آن روشها روی نمونه اولیه تعریف میشوند، اما ویژگیهای داده در سازنده تعریف میشوند، رایج است. دلیل این امر این است که روشها معمولاً برای هر شیء که ایجاد میکنیم یکسان هستند، در حالی که ما اغلب میخواهیم هر شیء مقدار خاص خود را برای ویژگیهای داده خود داشته باشد (دقیقاً مانند اینجا که هر شخص نام متفاوتی دارد).
ویژگیهایی که مستقیماً در شیء تعریف میشوند، مانند name در اینجا، ویژگیهای شخصی نامیده میشوند و میتوانید با استفاده از روش static بررسی کنید که آیا یک ویژگی، یک ویژگی شخصی است یا خیر:
همچنین میتوانید از متد غیر استاتیک در اینجا استفاده کنید، اما توصیه میکنیم در صورت امکان از استفاده کنید.
پروتوتایپها یک ویژگی قدرتمند و بسیار انعطافپذیر جاوا اسکریپت هستند که امکان استفاده مجدد از کد و ترکیب اشیاء را فراهم میکنند.
به طور خاص، آنها از نسخهای از وراثت پشتیبانی میکنند. وراثت یکی از ویژگیهای زبانهای برنامهنویسی شیگرا است که به برنامهنویسان اجازه میدهد این ایده را بیان کنند که برخی از اشیاء در یک سیستم، نسخههای تخصصیتری از اشیاء دیگر هستند.
به عنوان مثال، اگر ما در حال مدلسازی یک مدرسه هستیم، ممکن است اساتید و دانشجویانی داشته باشیم: آنها هر دو انسان هستند، بنابراین برخی ویژگیهای مشترک دارند (به عنوان مثال، هر دو نام دارند)، اما هر کدام ممکن است ویژگیهای اضافی اضافه کنند (به عنوان مثال، اساتید موضوعی دارند که تدریس میکنند)، یا ممکن است همان ویژگی را به روشهای مختلف پیادهسازی کنند. در یک سیستم OOP ممکن است بگوییم که اساتید و دانشجویان هر دو از افراد ارث میبرند.
میتوانید ببینید که چگونه در جاوا اسکریپت، اگر اشیاء استاد و دانشجو میتوانند پروتوتایپ شخص داشته باشند، میتوانند ویژگیهای مشترک را به ارث ببرند، در حالی که آن ویژگیهایی را که باید متفاوت باشند اضافه و تعریف مجدد میکنند.
در مقاله بعدی، وراثت را به همراه سایر ویژگیهای اصلی زبانهای برنامهنویسی شیگرا مورد بحث قرار خواهیم داد و خواهیم دید که جاوا اسکریپت چگونه از آنها پشتیبانی میکند.