نوعهای ارجاعی ECMAScript
- صفحه قبلی تغییر نوع ECMAScript
- صفحه بعدی عملگر یکتایی
نوعهای مرتبط معمولاً به عنوان کلاس (class) شناخته میشوند.
این آموزش به بررسی تعداد زیادی از نوعهای پیشتعریف شده ECMAScript خواهد پرداخت.
نوعهای مرتبط
نوعهای مرتبط معمولاً به عنوان کلاس (class) شناخته میشوند، یعنی، با برخورد به مقدار مرجع، با شیء سروکار داریم.
این آموزش به بررسی تعداد زیادی از نوعهای پیشتعریف شده ECMAScript خواهد پرداخت.
از اینجا به بعد، تمرکز بر نوعهای مرتبط با نوعهای اولیهای که قبلاً بحث شده است خواهد بود.
توجه داشته باشید:در معنای سنتی، ECMAScript واقعاً کلاسی ندارد. در واقع، به جای اینکه کلمه «کلاس» در ECMA-262 وجود داشته باشد، نشاندهنده این است که کلاس وجود ندارد. ECMAScript تعریف کرده است که «تعریف شیء»، از لحاظ منطقی معادل کلاسهای زبانهای برنامهنویسی دیگر است.
توجه:این آموزش از اصطلاح "شیء" استفاده خواهد کرد.
شیءها با استفاده از عبارت new و نام شیء مورد نظر ایجاد میشوند. به عنوان مثال، کد زیر یک نمونه از شیء Object ایجاد میکند:
var o = new Object();
این نحوه نوشتن مشابه زبان Java است، اما در ECMAScript هنگامی که بیش از یک پارامتر وجود دارد، استفاده از پرانتز الزامی است. اگر هیچ پارامتری وجود نداشته باشد، مانند کد زیر، پرانتز میتواند حذف شود:
var o = new Object;
توجه داشته باشید:با اینکه استفاده از پرانتز الزامی نیست، اما برای جلوگیری از سردرگمی، بهتر است از پرانتز استفاده کنید.
توجه:ما در فصل پایهای شیءها به طور عمیقتری به شیءها و رفتارهای آنها خواهیم پرداخت.
موضوع این بخش شیءهای دارای نوعهای اولیه مشابه است.
Object
شیء Object به خودی خود چندان مفید نیست، اما قبل از اینکه به دیگر کلاسها بپردازیم، باید آن را بشناسیم. زیرا شیء Object در ECMAScript مشابه java.lang.Object در Java است، همه شیءها در ECMAScript از این شیء ارث میبرند، همه ویژگیها و روشهای شیء Object در دیگر شیءها ظاهر میشوند، بنابراین با درک شیء Object، میتوان بهتر دیگر شیءها را درک کرد.
شیء Object دارای属性های زیر است:
- constructor
- اشاره به تابعی که شیء را ایجاد میکند (نشانگر). برای شیء Object، این نشانگر به تابع اولیه Object() اشاره دارد.
- Prototype
- اشاره به نمونهای از原型 شیء. برای همه شیءها، به طور پیشفرض به یک نمونه از شیء Object بازمیگردد.
شیء Object نیز چندین روش دارد:
- hasOwnProperty(property)
- تعیین اینکه آیا شیء دارای ویژگی خاصی است. باید این ویژگی را به صورت رشتهای مشخص کنید. (مثلاً o.hasOwnProperty("name"))
- IsPrototypeOf(object)
- تعیین اینکه آیا این شیء یک نمونه از یک شیء دیگر است.
- PropertyIsEnumerable
- تعیین اینکه آیا ویژگی داده شده قابل شمارش با استفاده از عبارت for...in است یا خیر.
- ToString()
- بازگشت نمودار اولیه شیء. برای شیء Object، ECMA-262 این ارزش را تعریف نکرده است، بنابراین ارزشهای مختلفی در اجرای مختلف ECMAScript وجود دارد.
- ValueOf()
- بازگشت به ارزش اولیه مناسب برای این شیء. برای بسیاری از شیءها، ارزشی که این روش بازمیگرداند با بازگشت ToString() یکسان است.
توضیحات:هر یک از ویژگیها و روشهای لیست شده در بالا توسط اشیاء دیگر پوشش داده میشوند.
اشیای Boolean
اشیای Boolean نوع مرجع نوع اولیه Boolean هستند.
برای ایجاد اشیای Boolean، فقط باید مقدار Boolean را به عنوان پارامتر ارسال کنید:
var oBooleanObject = new Boolean(true);
اشیای Boolean روش ValueOf() اشیای Object را برمیگرداند و مقدار اولیه را بازمیگرداند، یعنی true و false. روش ToString() نیز تغییر میکند و به عبارت
متاسفانه، در ECMAScript کمتر از اشیای Boolean استفاده میشود، حتی اگر استفاده شود، درک آن دشوار است.
مشکلات معمولاً در عبارات Boolean با استفاده از اشیای Boolean رخ میدهد. به عنوان مثال:
var oFalseObject = new Boolean(false); var bResult = oFalseObject && true; // خروجی true
در این کد، اشیای Boolean با مقدار false ایجاد میشود. سپس این مقدار با مقدار اولیه true عملیات AND انجام میدهد. در عملیات Boolean، نتیجه عملیات AND بین false و true false است. اما در این خط کد، oFalseObject محاسبه میشود، نه مقدار false آن.
همانطور که قبلاً بحث شده است، در عبارات Boolean، تمام اشیاء به صورت خودکار به true تبدیل میشوند، بنابراین مقدار oFalseObject true است. سپس true با true عملیات AND انجام میدهد، نتیجه true است.
توجه داشته باشید:اگرچه باید از قابلیت اشیای Boolean آگاه باشید، اما بهتر است از مقادیر اولیه Boolean استفاده کنید تا از مشکلاتی که در این بخش ذکر شده جلوگیری کنید.
مشاهده کنید
برای اطلاعات بیشتر در مورد اشیای Boolean، لطفاً به دستورالعمل اوبجکت Boolean جاوااسکریپت.
اشیای Number
همانطور که ممکن است فکر کنید، اشیای Number نوع مرجع نوع اولیه Number هستند. برای ایجاد اشیای Number، از کد زیر استفاده کنید:
var oNumberObject = new Number(68);
باید تا الان متوجه شده باشید که در بخشهای قبل این فصل، در مورد مقادیر خاص Number (مانند Number.MAX_VALUE) و اشیای Number صحبت شده است. تمام مقادیر خاص به عنوان ویژگیهای استاتیک اشیای Number هستند.
برای دریافت مقدار اولیه Number، فقط باید از روش valueOf() استفاده کنید:
var iNumber = oNumberObject.valueOf();
بالطبع، يحتوي أيضًا على طريقة toString()، التي تم مناقشتها بشكل مفصل في الفصل المتعلق بتحويل الأنواع.
إضافة إلى الطرق القياسية التي يتم استنساخها من Object، يحتوي Object Number على بعض الطرق المخصصة لتعامل الأرقام.
طريقة toFixed()
تعود طريقة toFixed() بنسخة من الرقم تحتوي على عدد محدد من الأرقام العشرية. على سبيل المثال:
var oNumberObject = new Number(68); alert(oNumberObject.toFixed(2)); //الخروج هو "68.00"
في هذا السياق، معامل طريقة toFixed() هو 2، مما يعني أن يجب عرض أرقام عشرية بعدد 2. يعود هذا الكود بـ "68.00"، ويتم تعويض الأرقام الفارغة بـ 0. هذا الكود مفيد جدًا في تطبيقات معالجة العملات. يمكن لطريقة toFixed() تمثيل أرقام تحتوي على من 0 إلى 20 رقماً عشرية، ويؤدي أي قيمة تزيد عن هذا الرقم إلى حدوث خطأ.
طريقة toExponential()
طريقة أخرى مرتبطة بتنسيق الأرقام هي toExponential()، التي تعود بنسخة من الرقم باستخدام النظام العشري.
مثل طريقة toFixed()، لها معامل يحدد عدد الأرقام العشرية التي يجب عرضها. على سبيل المثال:
var oNumberObject = new Number(68); alert(oNumberObject.toExponential(1)); //الخروج هو "6.8e+1"
نتيجة هذا الكود هي "6.8e+1"، كما تم شرحه سابقًا، يمثل 6.8x101المشكلة هي ماذا إذا لم تكن تعرف أي شكل يجب استخدامه (الشكل المسبق أو الشكل الأسي) لتمثيل الرقم؟ يمكنك استخدام طريقة toPrecision().
طريقة toPrecision()
يستخدم طريقة toPrecision() لتحويل الرقم إلى شكل مسبق أو شكل أسي. لديها معامل واحد، وهو عدد الأرقام المستخدمة لتمثيل العدد (باستثناء الأسي). على سبيل المثال،
var oNumberObject = new Number(68); alert(oNumberObject.toPrecision(1)); //الخروج هو "7e+1"
مهمة هذا الكود هي تمثيل العدد 68 برقم واحد، النتيجة هي "7e+1"، وبشكل آخر هو 70. بالتأكيد، يطبق طريقة toPrecision() تقريبًا على الأرقام.
var oNumberObject = new Number(68); alert(oNumberObject.toPrecision(2)); //الخروج هو "68"
البته، الخروج هو "68"، لأن هذا هو تمثيل الدالة الدقيق للعدد. ولكن ماذا إذا كان عدد الأرقام المحدد أكبر من الحاجة؟
var oNumberObject = new Number(68); alert(oNumberObject.toPrecision(3)); //نمایش "68.0"
در این حالت، toPrecision(3) معادل toFixed(1) است و "68.0" را نمایش میدهد.
روشهای toFixed()، toExponential() و toPrecision() عملیات تقریب را انجام میدهند تا یک عدد را با دقت صحیح با تعداد معینی از اعداد اعشاری نمایش دهند.
توجه:مانند Boolean، Number نیز مهم است، اما باید از این نوع به حداقل ممکن استفاده کنید تا از مشکلات احتمالی جلوگیری شود. هر زمان که ممکن است، از نمایشهای اولیه اعداد استفاده کنید.
مشاهده کنید
برای اطلاعات بیشتر در مورد Number به دستورالعمل اوبجکت Number جاوااسکریپت.
String
String به عنوان نمایی از نوع String اولیه ایجاد میشود که به صورت زیر ایجاد میشود:
var oStringObject = new String("hello world");
روشهای valueOf() و toString() String به یک مقدار اولیه از نوع String برمیگردند:
alert(oStringObject.valueOf() == oStringObject.toString()); //نمایش "true"
اگر این کد را اجرا کنید، نمایش "true" خواهد بود که نشان میدهد این مقادیر واقعاً برابر هستند.
توضیحات:String یکی از نوعهای پیچیدهتر ECMAScript است. همچنین، موضوع این بخش تنها به عملکرد پایه String اختصاص دارد. برای اطلاعات بیشتر در مورد عملکرد پیشرفته، بخشهای مرتبط با این آموزش را بخوانید یا به دستورالعمل اوبجکت String جاوااسکریپت.
ویژگی length
String دارای ویژگی length است که تعداد حروف رشته را نشان میدهد:
var oStringObject = new String("hello world"); alert(oStringObject.length); //نمایش "11"
این مثال "11" را نمایش میدهد، که تعداد حروف در "hello world" است. توجه داشته باشید که حتی اگر رشته شامل حروف دو بایتی باشد (در مقایسه با حروف ASCII که فقط یک بایت را اشغال میکنند)، هر حرف فقط یک حرف محسوب میشود.
روشهای charAt() و charCodeAt()
String در واقع دارای تعداد زیادی روش است.
در ابتدا، دو روش charAt() و charCodeAt() به یک حرف در رشته دسترسی دارند. هر دو این روش یک پارامتر دارند، یعنی موقعیت حرفی که میخواهید به آن دسترسی داشته باشید.
charAt() روشی است که حرف را در موقعیت مشخصی از رشته برمیگرداند:
var oStringObject = new String("hello world"); alert(oStringObject.charAt(1)); //نمایش "e"
در رشته "سلام دنیا"، حرف در موقعیت 1 "e" است. در بخش "ECMAScript نوعهای اولیه"، ما گفتیم که موقعیت اولین حرف 0 است، موقعیت دومین حرف 1 است و به همین ترتیب. بنابراین، فراخوانی charAt(1) "e" را برمیگرداند.
اگر میخواهید کد حرف را به جای حرف خود دریافت کنید، میتوانید روش charCodeAt() را فراخوانی کنید:
var oStringObject = new String("hello world"); alert(oStringObject.charCodeAt(1)); // خروجی "101"
این مثال "101" را خروجی میدهد، که کد حرف کوچک "e" است. در مثال زیر، alert(oStringObject.charCodeAt(1)); // خروجی "101"
روش concat()
در ادامه روش concat() آورده شده است، که برای اتصال یک یا چند رشته به مقدار اولیه شیء String استفاده میشود. این روش مقدار اولیه String را برمیگرداند و شیء String اصلی را تغییر نمیدهد:
var oStringObject = new String("سلام "); var sResult = oStringObject.concat("دنیا"); alert(sResult); // خروجی "سلام دنیا" alert(oStringObject); // خروجی "سلام \
در این کد، concat() روش به "سلام دنیا" برمیگرداند، در حالی که شیء String هنوز "سلام " است. به این دلیل، استفاده از علامت جمع (+) برای اتصال رشتهها بیشتر رایج است، زیرا این فرم از لحاظ منطقی نشان میدهد که واقعاً چه اتفاقی میافتد:
var oStringObject = new String("سلام "); var sResult = oStringObject + "دنیا"; alert(sResult); // خروجی "سلام دنیا" alert(oStringObject); // خروجی "سلام \
روشهای indexOf() و lastIndexOf()
تا کنون، روشهای اتصال رشتهها و دسترسی به حروف单独 در یک رشته را بحث کردهایم. اما اگر نمیدانید که آیا یک حرف خاص در یک رشته وجود دارد یا خیر، باید چه روشی را فراخوانی کنید؟ در این حالت، میتوانید روشهای indexOf() و lastIndexOf() را فراخوانی کنید.
روشهای indexOf() و lastIndexOf() هر دو موقعیت یک زیر رشته در یک رشته دیگر را برمیگردانند، اگر زیر رشته پیدا نشود، -1 را برمیگردانند.
تفاوت بین این دو روش این است که، روش indexOf() از ابتدای (موقعیت 0) رشته شروع به جستجو میکند، در حالی که روش lastIndexOf() از انتهای رشته شروع به جستجو میکند. به عنوان مثال:
var oStringObject = new String("سلام دنیا!"); alert(oStringObject.indexOf("o")); // خروجی "4" alert(oStringObject.lastIndexOf("o")); // خروجی "7"
در اینجا، اولین رشته "o" در موقعیت 4 قرار دارد، یعنی "hello" در "o"؛ آخرین رشته "o" در موقعیت 7 قرار دارد، یعنی "world" در "o". اگر این رشته فقط یک رشته "o" داشته باشد، موقعیتهای بازگشتی توسط روشهای indexOf() و lastIndexOf() یکسان هستند.
متد localeCompare()
روش بعدی localeCompare() است، که رشتهها را مرتب میکند. این متد یک پارامتر دارد - رشتهای که باید با آن مقایسه شود، و مقدار بازگشتی یکی از سه مقدار زیر است:
- اگر شیء رشته به ترتیب الفبا پیش از رشتهای که در پارامتر قرار دارد قرار دارد، مقدار منفی برمیگرداند.
- اگر شیء رشته برابر با رشتهای که در پارامتر قرار دارد باشد، مقدار 0 برمیگرداند
- اگر شیء رشته به ترتیب الفبا پس از رشتهای که در پارامتر قرار دارد قرار دارد، مقدار مثبت برمیگرداند.
توضیحات:اگر مقدار بازگشتی منفی باشد، معمولاً -1 است، اما مقدار واقعی بازگشتی توسط پیادهسازی تعیین میشود. اگر مقدار بازگشتی مثبت باشد، همچنین معمولاً 1 است، اما مقدار واقعی بازگشتی توسط پیادهسازی تعیین میشود.
مثال زیر را ببینید:
var oStringObject = new String("yellow"); alert(oStringObject.localeCompare("brick")); // خروجی "1" alert(oStringObject.localeCompare("yellow")); // خروجی "0" alert(oStringObject.localeCompare("zoo")); // خروجی "-1"
در این کد، رشته "yellow" با سه مقدار مقایسه شده است، یعنی "brick"، "yellow" و "zoo". به دلیل قرار گرفتن به ترتیب الفبا، "yellow" پس از "brick" قرار دارد، بنابراین localeCompare() 1 برمیگرداند؛ "yellow" برابر با "yellow" است، بنابراین localeCompare() 0 برمیگرداند؛ "zoo" پس از "yellow" قرار دارد، localeCompare() -1 برمیگرداند. یک بار دیگر تاکید میکنم که به دلیل اینکه مقدار بازگشتی توسط پیادهسازی تعیین میشود، بهترین روش برای فراخوانی متد localeCompare() به صورت زیر است:
var oStringObject1 = new String("yellow"); var oStringObject2 = new String("brick"); var iResult = oStringObject1.localeCompare(oStringObject2); if(iResult < 0) { alert(oStringObject1 + " پیش از " + oStringObject2); } alert(oStringObject1 + " پس از " + oStringObject2); } alert("دو رشته برابر هستند"); }
با استفاده از این ساختار، میتوان اطمینان حاصل کرد که این کد در همه اجراها به درستی اجرا میشود.
نکته خاص localeCompare() این است که منطقه (locale، که به کشور/منطقه و زبان نیز اشاره دارد) که این روش در آن اجرا میشود، دقیقاً روش اجرای این روش را مشخص میکند. در ایالات متحده، زبان انگلیسی زبان استاندارد ECMAScript است و localeCompare() حساس به حروف بزرگ و کوچک است، به این معنا که حروف بزرگ در ترتیب الفبایی پس از حروف کوچک قرار دارند. اما در مناطق دیگر ممکن است اینطور نباشد.
slice() و substring()
ECMAScript دو روش ارائه میدهد تا از یک توالی از کاراکترها یک رشته ایجاد شود، یعنی slice() و substring(). هر دو روش توالیای از کاراکترها را که باید پردازش شود، بازمیگردانند و هر دو یک یا دو پارامتر میپذیرند. پارامتر اول مکان شروع توالی مورد نظر است و پارامتر دوم (اگر استفاده شود) مکان پایان توالی قبل از پایان توالی است (یعنی کاراکتر در مکان پایان شامل در مقدار بازگردانده نمیشود). اگر پارامتر دوم حذف شود، مکان پایان به طور پیشفرض به طول رشته است.
مثل concat() روش، روشهای slice() و substring() هیچگاه مقدار خود String را تغییر نمیدهند. آنها تنها مقدار اصلی String را بازمیگردانند و String را تغییر نمیدهند.
var oStringObject = new String("hello world"); alert(oStringObject.slice("3")); // خروجی "lo world" alert(oStringObject.substring("3")); // خروجی "lo world" alert(oStringObject.slice("3", "7")); // خروجی "lo w" alert(oStringObject.substring("3", "7")); // خروجی "lo w"
در این مثال، استفاده از slice() و substring() مشابه است و نتایج نیز مشابه هستند. وقتی تنها پارامتر 3 وجود دارد، هر دو روش به "lo world" برمیگردند، زیرا "l" دومین "l" در "hello" در موقعیت 3 قرار دارد. وقتی دو پارامتر وجود دارد "3" و "7"، هر دو روش به "lo w" برمیگردند (حرف "o" در موقعیت 7 در "world" قرار دارد، بنابراین در نتیجه شامل نمیشود).
چرا دو روش کاملاً مشابه وجود دارد؟ در واقع، این دو روش کاملاً مشابه نیستند، اما تنها در صورتی که پارامترها منفی باشند، روشهای پردازش پارامترها کمی متفاوت است.
برای پارامترهای منفی، روش slice() از طول رشته و پارامتر را اضافه میکند، روش substring() آن را به عنوان 0 در نظر میگیرد (یعنی آن را نادیده میگیرد). به عنوان مثال:
var oStringObject = new String("hello world"); alert(oStringObject.slice("-3")); // خروجی "rld" alert(oStringObject.substring("-3")); // خروجی "hello world" alert(oStringObject.slice("3, -4")); // خروجی "lo w" alert(oStringObject.substring("3, -4")); // خروجی "hel"
به این ترتیب میتوان تفاوت اصلی بین slice() و substring() را مشاهده کرد.
وقتی تنها پارامتر -3 وجود دارد، slice() به "rld" برمیگردد، substring() اما به "hello world" برمیگردد. این به این دلیل است که برای رشته "hello world"، slice("-3") به slice("8") تبدیل میشود، و substring("-3") به substring("0") تبدیل میشود.
همانطور که انتظار میرود، با استفاده از پارامترهای 3 و -4 نیز تفاوتهای واضحی وجود دارد. slice() به slice(3, 7) تبدیل میشود، که مانند مثالهای قبلی، "lo w" را بازمیگرداند. در حالی که متد substring() دو پارامتر را به substring(3, 0) تبدیل میکند، که در واقع substring(0, 3) است، زیرا substring() همیشه عدد کوچکتر را به عنوان موقعیت شروع و عدد بزرگتر را به عنوان موقعیت پایان در نظر میگیرد. بنابراین، substring("3, -4") "hel" را بازمیگرداند. آخرین خط کد در اینجا برای توضیح نحوه استفاده از این روشها است.
toLowerCase()، toLocaleLowerCase()، toUpperCase() و toLocaleUpperCase()
آخرین مجموعهای از روشهایی که باید دربارهشان صحبت کنیم، تبدیل حروف بزرگ و کوچک است. 4 روش برای انجام تبدیل حروف بزرگ و کوچک وجود دارد، یعنی
- toLowerCase()
- toLocaleLowerCase()
- toUpperCase()
- toLocaleUpperCase()
با نام خودشان میتوان استفادهشان را فهمید، دو روش اول برای تبدیل یک رشته به تمام حروف کوچک استفاده میشوند و دو روش دوم برای تبدیل یک رشته به تمام حروف بزرگ استفاده میشوند.
toLowerCase() و toUpperCase() روشهای اصلی هستند و بر اساس همان روشهای java.lang.String پیادهسازی شدهاند.
toLocaleLowerCase() و toLocaleUpperCase() روشهای مبتنی بر منطقه هستند (مانند localeCompare() روشها). در بسیاری از مناطق، روشهای منطقهای خاص با روشهای عمومی کاملاً مشابه هستند. اما چندین زبان (مثلاً ترکی) از قوانین خاصی برای تبدیل حروف بزرگ و کوچک Unicode استفاده میکنند، بنابراین باید از روشهای منطقهای خاص استفاده کرد تا تبدیل صحیح انجام شود.
var oStringObject = new String("Hello World"); alert(oStringObject.toLocaleUpperCase()); // پخش "HELLO WORLD" alert(oStringObject.toUpperCase()); // پخش "HELLO WORLD" alert(oStringObject.toLocaleLowerCase()); // پخش "hello world" alert(oStringObject.toLowerCase()); // خروجی "hello world"
در این کد،toUpperCase() و toLocaleUpperCase() هر دو "HELLO WORLD" را خروجی میدهند، وtoLowerCase() و toLocaleLowerCase() هر دو "hello world" را خروجی میدهند. به طور کلی، اگر نمیدانید که یک زبان در چه کدی اجرا میشود، استفاده از روشهای خاص منطقهای امنتر است.
توجه:به یاد داشته باشید که تمام ویژگیها و روشهای اوبجکت String قابل اعمال بر روی مقادیر اولیه String هستند، زیرا آنها اوبجکتهای پseudo هستند.
عملگر instanceof
وقتی از نوع ذخیرهسازی مرجع استفاده میکنید، مشکلی پیش میآید، زیرا برای هر نوع اوبجکتی که ذخیره میکنید، این روش "object" برمیگرداند. ECMAScript یک عملگر دیگر به نام instanceof معرفی کرده است تا این مشکل را حل کند.
عملگر instanceof شبیه به عملگر typeof است و برای شناسایی نوع اوبجکتی که در حال پردازش آن هستیم استفاده میشود. برخلاف روش typeof، روش instanceof به توسعهدهنده اجازه میدهد تا به صورت مستقیم تأیید کند که اوبجکت به نوع خاصی تعلق دارد. به عنوان مثال:
var oStringObject = new String("hello world"); alert(oStringObject instanceof String); // خروجی "true"
این کد میپرسد که "آیا oStringObject نمونهای از اوبجکت String است؟" oStringObject قطعاً نمونهای از اوبجکت String است، بنابراین نتیجه "true" است. با این حال، در مقایسه با روش typeof، این روش انعطافپذیری کمتری دارد، اما همچنان در مواردی که typeof "object" برمیگرداند، بسیار مفید است.
- صفحه قبلی تغییر نوع ECMAScript
- صفحه بعدی عملگر یکتایی