از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
راهنمای درک کلاس ها در جاوا اسکریپت وقتی به کلاس ها و برنامه نویسی شی گرا به عنوان یک پارادایم فکر می کنید، جاوا اسکریپت احتمالا اولین زبانی نیست که به ذهنتان خطور می کند. در این راهنما، ما سعی می کنیم جاوا اسکریپت را بیشتر در لیست ارتباط ها قرار دهیم و در مورد چگونگی اعمال اصول شی گرا در حین نوشتن جاوا اسکریپت بحث کنیم.
سرفصلهای مطلب
معرفی
وقتی به آن فکر می کنید کلاس ها و برنامه نویسی شی گرا به عنوان یک پارادایم، جاوا اسکریپت احتمالا اولین زبانی نیست که به ذهن می رسد.
در این راهنما، ما سعی می کنیم جاوا اسکریپت را بیشتر در لیست انجمن ها قرار دهیم و در مورد روش اعمال بحث کنیم. اصول شی گرا هنگام نوشتن کد جاوا اسکریپت شایان ذکر است که برخی از ویژگی هایی که ما پوشش خواهیم داد هنوز در حال توسعه هستند، اما اکثر آنها در حال تولید هستند و به طور کامل کار می کنند. ما راهنما را به طور مناسب به هنگام انتشار آنها به روز خواهیم کرد.
از آنجایی که جاوا اسکریپت بیشتر استفاده می شود روی وب، استفاده از OOP روی آن میتواند واقعاً مفید باشد، مثلاً، دادههایی را از یک سرور (به عنوان مثال، مجموعهای از پایگاه داده MongoDB) دریافت کنید که میتوانید در یک کلاس با ویژگیها شکل دهید، زیرا کار با دادهها را بصریتر میکند. و راحت تر
برنامه نویسی شی گرا (OOP) چیست؟
قبل از شروع، اجازه دهید تعریف OOP و برخی از اصول اولیه را پوشش دهیم. اگر از قبل با این مفاهیم آشنا هستید، می توانید ادامه دهید و از آن بگذرید ساخت کلاس در جاوا اسکریپت.
برنامه نویسی شی گرا (OOP) محبوب ترین پارادایم برنامه نویسی در علوم کامپیوتر است. بلوک های اصلی ساختمان آن هستند اشیاء و کلاس ها. آ کلاس طرحی است که از آن اشیاء بوجود آمدند – اشیاء هستند نمونه ها از کلاس ها.
شما می توانید یک کلاس را به عنوان یک در نظر بگیرید دسته بندی، همچنین. هر کلاس میتواند دارای ویژگیها/ویژگیهایی باشد که حاوی مقادیر متفاوتی هستند و حالتهای نمونه کلاس (شیء) را توصیف میکنند. همچنین حاوی توابعی است (نامیده می شود مواد و روش ها) که معمولاً این ویژگیها و در نتیجه وضعیت نمونه فراخوانی یا نمونههای دیگر را تغییر میدهد یا اطلاعات مربوط به آن/همسایگانش را برمیگرداند.
کلاس و ویژگی ها
بگویید ما یک کلاس واقعا ساده به نام داریم ProgrammingLanguage
که دو ویژگی دارد – name
و founder
، که هر دو رشته هستند. این طرح ما برای ساخت یک شی است. یک شی از این کلاس دارای ویژگی ها و مقادیر است، مثلاً name = "JavaScript"
و founder = "Brendan Eich"
.
برای اینکه بتوانیم اشیایی مانند این را از یک کلاس خاص بسازیم، آن کلاس باید حاوی a باشد روش سازنده – یا به زودی، الف سازنده. یک سازنده عملاً یک کتابچه راهنما صحبت می کند روی چگونه نمونه سازی یک شی و اختصاص مقادیر. رایجترین روش برای ایجاد یک سازنده، نامگذاری آن به عنوان کلاس است، اما لزومی ندارد.
به عنوان مثال، برای ما ProgrammingLanguage
کلاس، a را تعریف می کنیم ProgrammingLanguage()
سازنده ای که تعریف می کند چگونه هنگام نمونهسازی، به ویژگیهای درون کلاس مقادیری اختصاص میدهیم. معمولا می پذیرد 0..n
آرگومان هایی که به عنوان مقادیر برای صفات استفاده می شوند:
class ProgrammingLanguage {
// Attributes
String name;
String founder;
// Constructor method
ProgrammingLanguage(string passedName, string passedFounder) {
name = passedName;
founder = passedFounder;
}
}
توجه داشته باشید: در حالی که مشابه است، این کد جاوا اسکریپت نیست و برای اهداف توضیحی است. زمانی که ما از جاوا اسکریپت استفاده خواهیم کرد کلاس درست کن.
سپس، هنگام نمونه سازی این کلاس، برخی از آرگومان ها را به سازنده منتقل می کنیم، با فراخوانی یک new
هدف – شی:
ProgrammingLanguage js = new ProgrammingLanguage("JavaScript", "Brendan Eich");
این یک شی از نوع ایجاد می کند ProgrammingLanguage
با صفات name="Javascript"
و founder="Brendan Eich"
.
روش های گتر و ستر
مجموعه دیگری از روش های کلیدی در OOP وجود دارد – گیرندگان و تنظیم کننده ها. همانطور که از نام آن پیداست، الف گیرنده متد مقادیری را دریافت می کند، در حالی که a تنظیم کننده آنها را تنظیم می کند.
در OOP، از آنها برای بازیابی ویژگی ها از یک شی استفاده می شود، به جای دسترسی مستقیم به آنها، برای کپسوله کردن آنها، انجام بررسی های احتمالی، و غیره. تنظیم کننده ها برای تنظیم ویژگی های اشیاء به مقادیر داده شده استفاده می شوند – دوباره، در یک کپسوله و ایزوله. شیوه.
توجه داشته باشید: برای محدود کردن واقعی این دسترسی، ویژگی ها معمولاً تنظیم می شوند private
(غیر قابل دسترسی در خارج از کلاس)، زمانی که زبان مورد نظر از اصلاح کننده های دسترسی پشتیبانی می کند.
به عنوان مثال، اگر بخواهید سن شخصی را تعیین کنید، ممکن است از شما جلوگیری شود -37
از طریق a تنظیم کننده، که اگر به شما اجازه دسترسی مستقیم به ویژگی ها داده شود، امکان اجرای آن وجود نخواهد داشت.
اگر از an استفاده می کنید، می توان از تنظیم کننده ها برای به روز رسانی یک مقدار یا تنظیم اولیه آن استفاده کرد خالی سازنده – یعنی سازنده ای که در ابتدا هیچ مقداری را تنظیم نمی کند.
قرارداد نامگذاری گیرنده ها و تنظیم کننده ها این است که باید پیشوند آنها باشد get
یا set
و به دنبال آن صفتی که با آن سروکار دارند قرار می گیرد:
getName() {
return name;
}
setName(newName) {
name = newName;
}
این این کلمه کلیدی
کلاس ها هستند خودآگاه. این this
کلمه کلیدی برای اشاره استفاده می شود این نمونه در یک کلاس، به محض اینکه نمونه سازی شود. شما فقط از کلمه کلیدی در کلاسی که به خودش اشاره دارد استفاده می کنید.
به عنوان مثال، در سازنده از قبل، از متغیرهای تصویب شده استفاده کرده ایم passedName
و passedFounder
، اما اگر اینها فقط بودند چه می شد name
و founder
کدام منطقی تر است؟
سازنده ما به شکل زیر خواهد بود:
ProgrammingLanguage(String name, String founder) {
name = name;
founder = founder;
}
بنابراین، کدام name
آیا تنظیم می کنیم که name
? آیا مقدار ارسال شده را روی ویژگی تنظیم می کنیم یا برعکس؟
اینجاست که this
کلیدواژه وارد می شود:
ProgrammingLanguage(String name, String name) {
this.name = name;
this.founder = founder;
}
اکنون، واضح است که ما مقدار آن را تنظیم می کنیم ویژگی این کلاس به مقدار ارسال شده از سازنده.
همین منطق در مورد گیرنده و تنظیم کننده ما نیز صدق می کند:
getName() {
return this.name;
}
setName(name) {
this.name = name;
}
ما در حال دریافت و تنظیم هستیم نام از این کلاس.
نحو صفات و سازنده ها و همچنین قراردادهای حروف بزرگ از زبانی به زبان دیگر متفاوت است، اما اصول اصلی OOP یکسان باقی می ماند.
با توجه به استانداردسازی سازنده ها، دریافت کننده ها و تنظیم کننده ها، امروزه اکثر IDE ها دارای یک میانبر یکپارچه برای ایجاد یک متد سازنده و همچنین دریافت کننده ها و تنظیم کننده ها هستند. تنها کاری که باید انجام دهید این است که ویژگی ها را تعریف کرده و آنها را از طریق میانبر مناسب در IDE خود ایجاد کنید.
اکنون که با مفاهیم OOP بیشتر آشنا شده ایم، می توانیم به OOP در جاوا اسکریپت بپردازیم.
ساخت کلاس در جاوا اسکریپت
توجه داشته باشید: یکی از تفاوتهایی که جاوا اسکریپت ایجاد میکند این است که هنگام تعریف کلاسها – لازم نیست صریحاً مشخص کنید که کدام ویژگیها/فیلدها را دارد. این بسیار انعطاف پذیرتر است و اشیاء هم کلاس می توانند داشته باشند زمینه های مختلف اگر شما چنین می خواهید باز هم، با توجه به این واقعیت که برخلاف اصول OOP است، از این کار دلسرد میشود، و عملکرد استاندارد شده تا حدی با داشتن سازندهای که در آن همه ویژگیها را تنظیم میکنید (و بنابراین، نوعی لیست ویژگیها را دارید) اعمال میشود.
در جاوا اسکریپت دو راه برای ساختن کلاس وجود دارد: استفاده از a اعلامیه کلاس و با استفاده از a بیان کلاس.
با استفاده از a اعلامیه کلاس، از طریق class
کلمه کلیدی، ما میتوانیم یک کلاس و تمام ویژگیها و متدهای آن را در براکتهای فرفری بعدی تعریف کنیم:
class Athlete {}
اینها را می توان در فایل های مربوطه خود یا در فایل دیگری، در کنار کدهای دیگر، به عنوان کلاس راحتی تعریف کرد.
روش دیگر، با استفاده از a عبارات کلاسی (با نام یا بدون نام) به شما امکان می دهد آنها را به صورت درون خطی تعریف و ایجاد کنید:
// Named
let Athlete = class Athlete{}
// Unnamed
let Athlete = class {}
// Retrieving the name attribute
console.log(Athlete.name);
بازیابی ویژگی مانند این توصیه نمی شود، همانطور که در روح OOP واقعی – ما نباید قادر به دسترسی مستقیم به ویژگی های یک کلاس باشیم.
از آنجایی که ما سازنده، یا گیرنده و تنظیم کننده نداریم، بیایید جلو برویم و آن ها را تعریف کنیم.
ایجاد سازنده، گیرنده و تنظیم کننده در جاوا اسکریپت
نکته دیگری که باید به آن توجه کنید جاوا اسکریپت است اجرا می کند نام سازنده باید نامگذاری شود constructor()
. اینجا همچنین جایی است که اساساً ویژگیهای کلاس خود را تعریف میکنید، البته کمی به طور ضمنیتر از زبانهایی مانند جاوا:
class Athlete{
constructor(name, height, weight) {
this._name = name;
this._height = height;
this._weight = weight;
}
}
const athlete = new Athlete("Michael Jordan", 198, 98);
اگر می خواهید ویژگی ها را از قبل تعریف کنید، شما می توان اما با توجه به ماهیت جاوا اسکریپت اضافی است، مگر اینکه بخواهید خصوصیات خصوصی ایجاد کنید. در هر صورت، باید نام ویژگی های خود را با پیشوند قرار دهید _
.
از آنجایی که جاوا اسکریپت برای پشتیبانی از کپسوله سازی خارج از جعبه استفاده نمی کرد، این راهی بود برای اطلاع رسانی به کاربران کلاس شما نه به دسترسی مستقیم به ویژگی ها اگر قبل از نام یک ویژگی زیرخط می بینید – به خود و سازنده کلاس لطف کنید و مستقیماً به آن دسترسی ندهید.
توجه داشته باشید: بود از نظر فنی امکان پذیر است برای تولید ویژگی های خصوصی در کلاس های جاوا اسکریپت، اما به طور گسترده مورد استفاده قرار نگرفت یا مورد استفاده قرار نگرفت – داگلاس کراکفورد پنهان کردن متغیرها را پیشنهاد کرد. در بسته شدن برای رسیدن به این اثر
شما می توانید بیشتر قصد خود را از طریق حاشیه نویسی کنید @access
حاشیه نویسی، نشان می دهد که می خواهید این ویژگی چه سطح دسترسی داشته باشد:
class Athlete {
/** @access private */
_name;
constructor(name) {
this._name = name;
}
getName() {
return this._name;
}
setName(name) {
this._name = name;
}
}
سپس میتوانید یک شی را نمونهسازی کنید، و همچنین ویژگی آن را دریافت و تنظیم کنید:
let athlete = new Athlete('Michael Jordan');
console.log(athlete.getName());
athlete.setName('Kobe Bryant');
console.log(athlete.getName());
این منجر به:
Michael Jordan
Kobe Bryant
شما همچنین می توانید مستقیماً به ملک دسترسی داشته باشید، هرچند:
console.log(athlete._name); // Michael Jordan
تنظیم فیلدها به عنوان خصوصی
سرانجام، زمینه های خصوصی معرفی شدند، و با پیشوند هستند #
. آنها در واقع استفاده از فیلدها را به خصوصی بودن اعمال می کنند نمی تواند خارج از کلاس قابل دسترسی باشد – فقط از طریق متدهایی که آن را در معرض دید قرار می دهند:
class Athlete {
/** @access private */
#name;
constructor(name) {
this.#name = name;
}
getName() {
return this.#name;
}
setName(name) {
this.#name = name;
}
}
let athlete = new Athlete('Michael Jordan');
console.log(athlete.getName()); // Michael Jordan
console.log(athlete.#name); // SyntaxError: Private field '#name' must be declared in an enclosing class
به این ترتیب، کپسولهسازی در واقع به دست میآید، زیرا کاربران فقط میتوانند از طریق روشهای بررسیشده به ویژگیهایی دسترسی داشته باشند که میتوانند مقادیر بازگشتی را تأیید کنند، یا آنها را از تنظیم مقادیر غیرمنتظره، مانند اختصاص یک عدد بهجای یک رشته به رشته، بازدارند. #name
صفت.
توجه داشته باشید: برای علامت گذاری یک ویژگی به عنوان خصوصی، باید آن را قبل از دریافت کننده ها و تنظیم کننده ها اعلام کنید. این ویژگی از سال 2018 فعال بوده است (Babel 7.0+) اما ممکن است کار نکند روی برخی از محیط های قدیمی تر
این گرفتن و تنظیم کلید واژه ها
از طرف دیگر، جاوا اسکریپت دارای مجموعه خاصی از کلمات کلیدی است – get
و set
، که می توان از آن برای ساخت گیر و ستر استفاده کرد. هنگام استفاده، آنها بستن ویژگی های خاصی برای توابع فراخوانی شده زمانی که شما می خواهید به آنها دسترسی داشته باشید.
استفاده از یک نام بین یک ویژگی و متدهای گیرنده/ستتر محدود شده توسط یک قرارداد معمول است get
و set
، بدون یک پیشوند (زیاد خواهد بود):
class Athlete {
constructor(name) {
this._name = name;
}
get name() {
return this._name;
}
set name(name) {
this._name = name;
}
}
let athlete = new Athlete("Michael Jordan");
console.log(athlete.name); // Output: Michael Jordan
athlete.name = "Kobe Bryant";
console.log(athlete.name); // Output: Kobe Bryant
اگرچه ممکن است به نظر برسد، اما ما هستیم نه دسترسی به _name
مستقیماً مشخص شود. ما به طور ضمنی تماس می گیریم name()
روش، توسط تلاش کردن برای دسترسی به ویژگی، زمانی که آن درخواست به مسیر مجدد هدایت شود get name()
روش. برای روشن تر شدن این موضوع، اجازه دهید آن را اصلاح کنیم get name()
بدن روش:
get name() {
return "Name: " + this._name;
}
حالا این:
let athlete = new Athlete('Michael Jordan')
console.log(athlete.name);
منجر می شود به:
Name: Michael Jordan
توجه داشته باشید: دلیل دیگری برای اضافه کردن خط زیر (_
) برای تعیین نام ها در صورتی است که از این رویکرد برای تعریف گیرنده ها و تنظیم کننده ها استفاده کنید. اگر قرار بود فقط استفاده کنیم name
به عنوان ویژگی، با توجه به این واقعیت مبهم خواهد بود name
می توان نیز رجوع شود get name()
.
به محض اینکه ما سعی می کنیم کلاس را نمونه سازی کنیم، یک حلقه بازگشتی شروع می شود و پشته تماس را پر می کند تا زمانی که حافظه آن تمام شود:
class Athlete {
constructor(name) {
this.name = name;
}
get name() {
return this.name;
}
set name(name) {
this.name = name;
}
}
let athlete = new Athlete('Michael Jordan');
console.log(athlete.name);
که منجر به:
script.js:12
this.name = name;
^
RangeError: Maximum call stack size exceeded
از توابع یا کلمات کلیدی Getter/Setter استفاده می کنید؟
کدام رویکرد بهتر است؟
جامعه در انتخاب بین این دو تقسیم شده است و برخی از توسعه دهندگان یکی را بر دیگری ترجیح می دهند. هیچ برنده مشخصی وجود ندارد و هر دو رویکرد با اجازه دادن به کپسولهسازی از اصول OOP پشتیبانی میکنند و میتوانند ویژگیهای خصوصی را برگردانند و تنظیم کنند.
تعریف روش های کلاس
قبلاً چند روش را تعریف کرده ایم، یعنی متدهای گیرنده و تنظیم کننده. به همین ترتیب، میتوانیم روشهای دیگری را تعریف کنیم که وظایف دیگری را انجام میدهند.
دو روش اصلی برای تعریف روش ها وجود دارد – در کلاس و خارج از کلاس.
تا کنون، ما از تعاریف درون کلاسی استفاده کردهایم:
class Athlete {
// Constructor, getters, setters
sayHello() {
return "Hello, my name is " + this.name;
}
}
console.log(athlete.sayHello()) // Hello, my name is Kobe Bryant
به طور متناوب، می توانید به صراحت یک تابع را از طریق یک اعلان تابع، خارج از یک کلاس ایجاد کنید:
class Athlete {
// Class code
}
athlete.sayHello = function() {
return "Hello, my name is " + athlete.name;
}
let athlete = new Athlete("Kobe Bryant");
console.log(athlete.sayHello()) // Output: Hello, my name is Kobe Bryant
برای جاوا اسکریپت، هر یک از این رویکردها یکسان است، بنابراین میتوانید هر کدام را که مناسبتر است انتخاب کنید.
ارث بری کلاس در جاوا اسکریپت
مفهوم کلیدی OOP این است وراثت طبقاتی. آ زیر کلاس (کلاس کودک) می تواند باشد تمدید شده از یک کلاس و تعریف خواص و متدهای جدید، while به ارث بردن برخی از آن سوپرکلاس (کلاس والدین).
یک Athlete
می تواند باشد BasketballPlayer
، TennisPlayer
یا الف FootballPlayer
اما هر سه اینها نمونه ای از یک هستند Athlete
.
در جاوا اسکریپت، extends
کلمه کلیدی برای ایجاد یک زیر کلاس استفاده می شود:
// Athlete class definition
class BasketballPlayer extends Athlete {
constructor(name, height, weight, sport, teamName) {
super(name, height, weight);
this._sport = sport;
this._teamName = teamName;
}
get sport() {
return this._sport;
}
get teamName() {
return this._teamName;
}
}
const bp = new BasketballPlayer("LeBron James", 208, 108, "Basketball", "Los Angeles Lakers");
ما یک شی از BasketballPlayer
کلاس که شامل ویژگی های استفاده شده در Athlete
کلاس، و همچنین دو ویژگی جدید، sport
و teamName
– که مخصوص هستند BasketballPlayer
کلاس
مشابه روش this
اشاره دارد به این کلاس، super()
به سوپرکلاس اشاره دارد. با تماس super()
با آرگومانها، سازنده superclass را فراخوانی میکنیم، چند ویژگی را تنظیم میکنیم، قبل از اینکه ویژگیهای جدید را تنظیم کنیم. BasketballPlayer
کلاس
وقتی از extends
کلمه کلیدی، ما تمام متدها و ویژگی های موجود در سوپرکلاس را به ارث می بریم – به این معنی که ما به ارث برده ایم sayHello()
متد، گیرندهها و تنظیمکنندهها و همه ویژگیها. ما می توانیم با استفاده از آن روش جدید ایجاد کنیم و روش های بیشتری به آن اضافه کنیم، مانند این:
class BasketballPlayer extends Athlete {
// ... previous code
fullIntroduction() {
return this.sayHello() + " and I play " + this.sport + " in " + this.teamName;
}
}
const bp = new BasketballPlayer("LeBron James", 208, 108, "Basketball", "Los Angeles Lakers");
console.log(bp.fullIntroduction());
که منجر به:
Hello, my name is LeBron James and I play Basketball in Los Angeles Lakers
توجه داشته باشید: ما a را تعریف نکرده ایم sayHello()
روش در BasketballPlayer
کلاس، اما همچنان می تواند از طریق آن به آن دسترسی داشته باشد this
. چطور؟ آیا بخشی از آن نیست Athlete
کلاس؟ این است. ولی BasketballPlayer
این روش را به ارث برده است بنابراین آن را به خوبی که در تعریف شده است BasketballPlayer
کلاس
این به عنوان مثال از اپراتور
این instanceof
عملگر برای بررسی اینکه آیا یک شیء an است یا خیر استفاده می شود به عنوان مثال از یک طبقه خاص نوع برگشتی a است boolean
:
let bp = new BasketballPlayer();
let athlete = new Athlete();
console.log(bp instanceof BasketballPlayer); // Output: true
console.log(bp instanceof Athlete); // Output: true
console.log(athlete instanceof Athlete); // Output: true
console.log(athlete instanceof BasketballPlayer); // Output: false
آ BasketballPlayer
هست یک Athlete
بنابراین bp
نمونه ای از هر دو است. از سوی دیگر، یک Athlete
لازم نیست یک باشد BasketballPlayer
، بنابراین athlete
فقط یک نمونه از Athlete
. اگر ما را نمونه کنیم Athlete
به عنوان یک بسکتبالیست، مانند bp
، آنها نمونه ای از هر دو هستند.
نتیجه
در این راهنما، نگاهی به برخی از اصول اولیه OOP و همچنین روش کار کلاس ها در جاوا اسکریپت انداخته ایم. جاوا اسکریپت هنوز کاملاً برای OOP مناسب نیست، اما گامهایی برای تطبیق بیشتر این عملکرد در حال انجام است.
ما تعاریف کلاس، ویژگی ها، دریافت کننده ها، تنظیم کننده ها، کپسولاسیون، روش های کلاس و وراثت را بررسی کرده ایم.
منتشر شده در 1403-01-15 21:15:03