مقدمه
نمونه های اولیه مکانیزمی هستند که توسط آن اشیاء جاوا اسکریپت ویژگی ها را از یکدیگر به ارث می برند. در این مقاله توضیح میدهیم که یک نمونه اولیه چیست، زنجیرههای نمونه اولیه چگونه کار میکنند و چگونه میتوان یک نمونه اولیه برای یک شی را تنظیم کرد.
پیش نیازها
درک توابع جاوا اسکریپت، آشنایی با مبانی جاوا اسکریپت (به مراحل اولیه و بلوک های ساختمان مراجعه کنید)، و اصول OOJS (به مقدمه اشیاء مراجعه کنید).
زنجیره نمونه اولیه
در کنسول مرورگر، سعی کنید یک شی به معنای واقعی کلمه ایجاد کنید:
const myObject = {
city: "Madrid",
greet() {
console.log(`Greetings from ${this.city}`);
},
};
myObject.greet(); // Greetings from Madrid
این یک شی با یک ویژگی داده، شهر، و یک متد، greet() است. اگر نام شی و به دنبال آن یک نقطه را در کنسول تایپ کنید، مانند myObject.، کنسول لیستی از تمام ویژگی های موجود برای این شی را نمایش می دهد. خواهید دید که علاوه بر شهر و سلام، بسیاری از خواص دیگر نیز وجود دارد!
__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
valueOf
سعی کنید به یکی از آنها دسترسی داشته باشید:
myObject.toString(); // "[object Object]"
کار می کند (حتی اگر مشخص نباشد که ()toString چه می کند).
این خواص اضافی چیست و از کجا می آیند؟
هر شی در جاوا اسکریپت دارای یک ویژگی داخلی است که به آن نمونه اولیه می گویند. نمونه اولیه به خودی خود یک شی است، بنابراین نمونه اولیه نمونه اولیه خود را خواهد داشت و چیزی را که یک زنجیره اولیه نامیده می شود، می سازد. این زنجیره زمانی به پایان می رسد که به یک نمونه اولیه برسیم که برای نمونه اولیه خود null دارد.
نکته: به خاصیت یک شی که به نمونه اولیه آن اشاره می کند، نمونه اولیه نمی گویند. نام آن استاندارد نیست، اما در عمل همه مرورگرها از __proto__ استفاده می کنند. روش استاندارد برای دسترسی به نمونه اولیه یک شی، متد ()Object.getPrototypeOf است.
هنگامی که سعی می کنید به ویژگی یک شی دسترسی پیدا کنید: اگر ویژگی در خود شی پیدا نشود، نمونه اولیه برای ویژگی جستجو می شود. اگر هنوز خاصیت پیدا نشد، نمونه اولیه نمونه جستجو میشود و به همین ترتیب تا زمانی که خاصیت پیدا شود یا به انتهای زنجیره برسد، در این صورت undefined برگردانده میشود.
بنابراین وقتی myObject.toString() را فرا میخوانیم، مرورگر:
- به دنبال toString در myObject می گردد
- نمی توانم آن را در آنجا پیدا کنم، بنابراین در نمونه اولیه شی myObject برای toString جستجو می کند
- آن را در آنجا پیدا می کند و با آن تماس می گیرد.
نمونه اولیه برای myObject چیست؟ برای فهمیدن، می توانیم از تابع Object.getPrototypeOf():
Object.getPrototypeOf(myObject); // Object { }
این یک شی به نام Object.prototype است و ابتدایی ترین نمونه اولیه است که همه اشیا به طور پیش فرض دارند. نمونه اولیه Object.prototype پوچ است، بنابراین در انتهای زنجیره نمونه اولیه قرار دارد:
نمونه اولیه یک شی همیشه Object.prototype نیست. این را امتحان کن:
const myDate = new Date();
let object = myDate;
do {
object = Object.getPrototypeOf(object);
console.log(object);
} while (object);
// Date.prototype
// Object { }
// null
این کد یک شی Date ایجاد می کند، سپس زنجیره نمونه اولیه را بالا می برد و نمونه های اولیه را ثبت می کند. به ما نشان می دهد که نمونه اولیه myDate یک شی Date.prototype است و نمونه اولیه آن Object.prototype است.
در واقع، وقتی متدهای آشنا را فراخوانی می کنید، مانند myDate2.getTime()، متدی را فراخوانی می کنید که در Date.prototype تعریف شده است.
خواص سایه زنی
چه اتفاقی میافتد اگر یک خاصیت را در یک شی تعریف کنید، وقتی یک ویژگی با همان نام در نمونه اولیه شی تعریف شود؟ اجازه بدید ببینم:
const myDate = new Date(1995, 11, 17);
console.log(myDate.getTime()); // 819129600000
myDate.getTime = function () {
console.log("something else!");
};
myDate.getTime(); // 'something else!'
این باید با توجه به توصیف زنجیره نمونه اولیه قابل پیش بینی باشد. هنگامی که ما getTime() را فراخوانی می کنیم، مرورگر ابتدا در myDate به دنبال ویژگی با آن نام می گردد و تنها در صورتی نمونه اولیه را بررسی می کند که myDate آن را تعریف نکرده باشد. بنابراین وقتی getTime() را به myDate اضافه می کنیم، نسخه موجود در myDate فراخوانی می شود.
به این می گویند “سایه زدن” ملک.
تنظیم یک نمونه اولیه
راههای مختلفی برای تنظیم نمونه اولیه یک شی در جاوا اسکریپت وجود دارد، و در اینجا دو مورد را شرح میدهیم: Object.create() و سازنده.
با استفاده از Object.create
متد Object.create() یک شی جدید ایجاد می کند و به شما امکان می دهد یک شی را مشخص کنید که به عنوان نمونه اولیه شی جدید استفاده می شود.
در اینجا یک مثال است:
const personPrototype = {
greet() {
console.log("hello!");
},
};
const carl = Object.create(personPrototype);
carl.greet(); // hello!
در اینجا یک شی personPrototype ایجاد می کنیم که دارای متد greet() است. سپس از Object.create() برای ایجاد یک شی جدید با personPrototype به عنوان نمونه اولیه آن استفاده می کنیم. اکنون میتوانیم greet() را روی شی جدید فراخوانی کنیم و نمونه اولیه اجرای آن را فراهم میکند.
با استفاده از سازنده
در جاوا اسکریپت، همه توابع دارای یک ویژگی به نام پروتوتایپ هستند. وقتی یک تابع را به عنوان سازنده فراخوانی می کنید، این ویژگی به عنوان نمونه اولیه شی جدید ساخته شده تنظیم می شود (طبق قرارداد، در ویژگی با نام __proto__).
بنابراین اگر نمونه اولیه یک سازنده را تنظیم کنیم، می توانیم اطمینان حاصل کنیم که تمام اشیاء ایجاد شده با آن سازنده، آن نمونه اولیه داده می شود:
const personPrototype = {
greet() {
console.log(`hello, my name is ${this.name}!`);
},
};
function Person(name) {
this.name = name;
}
Object.assign(Person.prototype, personPrototype);
// or
// Person.prototype.greet = personPrototype.greet;
در اینجا ما ایجاد می کنیم:
- یک شی personPrototype که دارای متد greet() است
- یک تابع سازنده ()Person که نام شخصی که باید ایجاد شود را مقداردهی اولیه می کند.
سپس متدهای تعریف شده در personPrototype را با استفاده از Object.assign در ویژگی نمونه اولیه تابع Person قرار می دهیم.
پس از این کد، اشیاء ایجاد شده با استفاده از ()Person.prototype را به عنوان نمونه اولیه خود دریافت می کنند که به طور خودکار حاوی متد greet است.
const reuben = new Person("Reuben");
reuben.greet(); // hello, my name is Reuben!
این همچنین توضیح می دهد که چرا قبلاً گفتیم که نمونه اولیه myDate Date.prototype نامیده می شود: این ویژگی نمونه اولیه سازنده Date است.
Property خود
اشیایی که با استفاده از سازنده Person در بالا ایجاد می کنیم، دو ویژگی دارند:
- یک ویژگی name، که در سازنده تنظیم شده است، بنابراین مستقیماً در اشیاء Person ظاهر می شود
- یک متد greet() که در نمونه اولیه تنظیم شده است.
دیدن این الگو معمول است، که در آن متدها بر روی نمونه اولیه تعریف میشوند، اما ویژگیهای داده در سازنده تعریف میشوند. دلیلش این است که روشها معمولاً برای هر شیئی که ایجاد میکنیم یکسان هستند، در حالی که ما اغلب میخواهیم هر شی ارزش خاص خود را برای ویژگیهای دادهاش داشته باشد (همانطور که در اینجا هر شخص نام متفاوتی دارد).
ویژگی هایی که مستقیماً در شی تعریف می شوند، مانند name در اینجا، ویژگی های خود نامیده می شوند و می توانید با استفاده از متد استاتیک Object.hasOwn () بررسی کنید که آیا یک ویژگی یک ویژگی خاص است یا خیر:
const irma = new Person("Irma");
console.log(Object.hasOwn(irma, "name")); // true
console.log(Object.hasOwn(irma, "greet")); // false
توجه: در اینجا میتوانید از روش غیراستاتیک Object.hasOwnProperty() نیز استفاده کنید، اما توصیه میکنیم در صورت امکان از Object.hasOwn() استفاده کنید.
نمونه های اولیه و وراثت
نمونه های اولیه یک ویژگی قدرتمند و بسیار انعطاف پذیر جاوا اسکریپت هستند که امکان استفاده مجدد از کد و ترکیب اشیاء را فراهم می کنند.
آنها به طور خاص از نسخه ای از ارث پشتیبانی می کنند. وراثت یکی از ویژگی های زبان های برنامه نویسی شی گرا است که به برنامه نویسان اجازه می دهد این ایده را بیان کنند که برخی از اشیاء در یک سیستم نسخه های تخصصی تری از اشیاء دیگر هستند.
به عنوان مثال، اگر ما در حال الگوبرداری از یک مدرسه هستیم، ممکن است اساتید و دانشآموزان داشته باشیم: آنها هر دو نفر هستند، بنابراین ویژگیهای مشترکی دارند (مثلاً هر دو نام دارند)، اما هر کدام ممکن است ویژگیهای اضافی اضافه کنند (مثلاً اساتید موضوعی دارند که آنها تدریس می کنند)، یا ممکن است همان ویژگی را به روش های مختلف پیاده سازی کنند. در یک سیستم OOP ممکن است بگوییم که اساتید و دانشجویان هر دو از مردم ارث می برند.
میتوانید ببینید که چگونه در جاوا اسکریپت، اگر اشیاء Professor و Student میتوانند نمونههای اولیه Person داشته باشند، میتوانند ویژگیهای مشترک را به ارث ببرند، در حالی که ویژگیهایی را که نیاز به تفاوت دارند اضافه و دوباره تعریف میکنند.
در مقاله بعدی در مورد وراثت به همراه سایر ویژگی های اصلی زبان های برنامه نویسی شی گرا بحث خواهیم کرد و خواهیم دید که جاوا اسکریپت چگونه از آنها پشتیبانی می کند.
نتیجه
این مقاله به نمونههای اولیه اشیاء جاوا اسکریپت میپردازد، از جمله اینکه چگونه زنجیرههای شی نمونه اولیه به اشیا اجازه میدهند ویژگیها را از یکدیگر به ارث ببرند، ویژگی نمونه اولیه و نحوه استفاده از آن برای افزودن متدها به سازندهها و سایر موضوعات مرتبط.