جاوااسکریپت زبانی است که یادگیری آن در سطوح ابتدایی آسان است اما عمیق شدن در آن کمی دشوار به نظر میرسد چرا که یکسری قابلیتها و سینتکسهای پیچیدهای دارا است به طوری که یک دولوپر باتجربه پس از سالها کدنویسی با این زبان نیز نمیتواند ادعای آشنایی با زیروبم جاوااسکریپت را داشته باشد! در همین راستا، در این مقاله قصد داریم تا برخی از فیچرهای این زبان را بیان کنیم که ممکن است دولوپرهای تازهکار با آنها ناآشنا باشند.
اپراتور void
یک اپراتور به اصطلاح Unary (تکمنظوره) است که تنها برای اجرای دستور مد نظر بدون ریترن کردن مقداری از آن به کار گرفته میشود و مقدار undefined
را در خروجی ریترن میکند برای مثال کدهای زیر را در نظر بگیرید:
void 0
void (0)
هر دو دستور فوق معادل یکدیگر بوده و مقادیر ریترنشده برای هر یک از آنها خروجی undefined
خواهد بود که به منزلۀ دستور دادن به مرورگر برای انجام ندادن کاری مورد استفاده قرار میگیرند. به عنوان مثالی دیگر داریم:
void(1 === 1);
void anyFunction();
در کد بالا دستور سطر اول یک مقایسۀ درست میباشد که دو عدد از نظر مقدار و نوع با هم برابر بوده و باید مقدار true
در خروجی ریترن شود اما به دلیل استفاده از اپراتور void
مقداری مبنی بر درست بودن این مقایسه در خروجی ریترن نخواهد شد. همانطور که در خط دوم مشاهده میشود، استفاده از این کیورد برای تعریف فانکشنها نیز منجر بدین خواهد شد تا فانکشن مد نظر اجرا شده اما مقداری را در خروجی ریترن نکند (برای آشنایی با سایر اپراتورهای این زبان به مقالۀ درآمدی بر اپراتورها در زبان جاوااسکریپت مراجعه نمایید.)
اختیاری بودن پرانتز برای ساخت Object
پرانتزهایی که بعد از نام کلاس جهت ساخت یک آبجکت جدید میآوریم اختیاری هستند که بدین طریق در هنگام فراخوانی کانستراکتور میتوانیم از پاس دادن آرگومان ورودی به آن خودداری کنیم. در همین راستا در ادامه سه نمونه کد معتبر در این زبان را هم با استفاده از پرانتز و هم بدون استفاده از آن آوردهایم:
const date = new Date();
const month = new Date().getMonth();
const myInstance = new MyClass();
همانطور که در کد فوق میبینید سه نمونه آبجکت ساختهایم که در هر یک از آنها نیز علائم ()
را به کار بردهایم اما در عین حال امکان تغییر دستورهای فوقالذکر را به صورت زیر داریم:
const date = new Date;
const month = (new Date).getMonth();
const myInstance = new MyClass;
هر یک از این دستورها نیز در زبان جاوااسکریپت معتبر بوده و به منزلۀ ساخت آبجکت جدید از کلاسهای مد نظر هستند که البته وقتی علائم ()
درج نشوند نمیتوان آرگومانی را به عنوان ورودی به کانستراکتور فراخوانیشده از کلاس مد نظر پاس داد.
عدم استفاده از پرانتز برای تعریف IIFE
IIFE مخفف عبارت Immediately Invoked Functional Expression بوده و به فانکشنهایی اشاره دارد که به صورت بینام تعریف شده و به محض تعریف نیز اجرا میشوند که میتوانیم آنها را بدون پرانتزهای ابتدایی نیز تعریف کنیم. در ادامه، نمونهای از سینتکس معتبر پیادهسازی یک به اصطلاح IIFE را آوردهایم:
(function (){
console.log('Normal IIFE called')
}
)()
در کد فوق با استفاده از پرانتزهای ابتدایی به مفسر جاوااسکریپت گفتهایم که اسکریپت مد نظر یک دستور فانکشنال است و تحت هیچ عنوان فانکشنی نیست تا به محض تعریف اجرا گردد و در ادامه با بهکارگیری کیورد function
یک فانکشن بینام تعریف کرده و گفتهایم در صورت اجرا، استرینگ «Normal IIFE called» در خروجی چاپ شود. حال اگر بخواهیم فانکشن بینام فوق را بدون استفاده از پرانتزهای ابتدایی تعریف کنیم، خواهیم داشت:
void function (){
console.log('Normal IIFE called')
}()
در کد فوق با حذف پرانتزهای ابتدایی، اپراتور void
را برای تعریف فانکشن بینام به کار گرفتهایم و بدین وسیله به مفسر جاوااسکریپت دستور میدهیم که کد مد نظر یک دستور فانکشنال است و به محض تعریف باید اجرا شود و از همین روی میتوانیم از آوردن ()
در ابتدا خودداری کنیم اما همانطور که کمی قبلتر بیان کردیم، اپراتور void
منجر بدین میشود که فانکشن بینام فوقالذکر مقداری را در خروجی ریترن نکند که در صورت نیاز به ریترن شدن نتیجه میتوان به جای استفاده از اپراتور void
فانکشن مذکور را به یک متغیر دلخواه منتسب کرد که بدین ترتیب دیگر نیازی به آوردن پرانتزهای ابتدایی نخواهد بود و نتیجۀ حاصل از اجرای فانکشن در متغیر مذکور نگاهداری شده و میتوانیم در صورت نیاز آن را مورد استفاده قرار دهیم که برای این منظور کدهای فوق را به صورت زیر ریفکتور کردهایم:
result = (function () {
return 'SokanAcademy.com'
})()
در کد فوق متغیری تحت عنوان result
تعریف کرده و فانکشن بینامی را به روش متداول و با استفاده از پرانتزهای ابتدایی تعریف کردهایم که این وظیفه را دارا است تا استرینگ «SokanAcademy.com» را در خروجی ریترن کند و نتیجۀ حاصل از اجرای این فانکشن در متغیر result
نگاهداری میشود اما اگر بخواهیم فانکشن بینام فوق را بدون ذکر پرانتزهای ابتدایی تعریف کنیم، خواهیم داشت:
result = function () {
return 'SokanAcademy.com'
}()
مجدداً در کد فوق فانکشن بینام مد نظر را به متغیری تحت عنوان result
منتسب کردهایم که بدین ترتیب میتوانیم از آوردن پرانتزهای ابتدایی برای تعریف فانکشن به اصطلاح IIFE خودداری کنیم و در نتیجۀ اجرای دستور فوق استرینگ زیر در خروجی ریترن خواهد شد:
SokanAcademy.com
استرینگ بالا نتیجۀ حاصل از اجرای دستور فانکشنال فوقالذکر بوده و در متغیر result
نگاهداری میشود.
دستور ()Function
در زبان برنامهنویسی جاوااسکریپت استفاده از کیورد function
تنها راه به منظور تعریف فانکشنها نیست بلکه این زبان قابلیتی دارا است که در آن میتوانیم با بهکارگیری دستور ()Function
با حرف اول بزرگ و به همراه کیورد new
یک فانکشن جدید را تعریف کنیم:
var multiply = new Function("x", "y", "return x*y;");
multiply (2,3)
در کد فوق فانکشنی تحت عنوان ()multiply
را با بهکارگیری کیوردهای ()new Function
تعریف کردهایم بدین صورت که دو آرگومان ورودی x
و y
برای آن تعریف کرده و گفتهایم دستور x*y
روی پارامترهای ورودی مد نظر اِعمال شود که در واقع آرگومان آخر به عنوان بدنۀ فانکشن مذکور خواهد بود. جهت تست نیز فانکشن ()multiply
را با دو پارامتر ورودی 2 و 3 فراخوانی کردهایم که نتیجۀ حاصل از اجرای آن، ریترن شدن عدد 6 در خروجی خواهد بود.
افزودن یکسری Property متناسب با نیاز اپلیکیشن به فانکشنها
جاوااسکریپت یک زبان شیئگرا است که در آن فانکشنها نیز به عنوان آبجکت در نظر گرفته میشوند و بنابراین میتوانیم ویژگیهای مد نظر خود را به فانکشنها اضافه کنیم. برای مثال، در ادامه قصد داریم فانکشنی تحت عنوان ()greet
تعریف کنیم که به ازای شرایط مختلف، استرینگهای متفاوتی را در خروجی ریترن کند که در همین راستا داریم:
function greet() {
if (greet.locale === 'fr') {
console.log('Bonjour!')
} else if (greet.locale === 'es') {
console.log('Hola!')
} else {
console.log('Hello!')
}
}
در کد فوق فانکشنی تحت عنوان ()greet
تعریف کردهایم و در آن آبجکتی به نام locale
ساختهایم که به ترتیب زیر عمل میکند:
- چنانچه مقدار استرینگ ورودی برای این آبجکت برابر با «fr» باشد، فانکشن مد نظر استرینگ «!Bonjour» را در خروجی چاپ میکند.
- اگر مقدار استرینگ ورودی را برابر با عبارت «es» قرار دهیم، فانکشن مد نظر استرینگ «!Hola» را در خروجی چاپ میکند.
- و در باقی شرایط نیز استرینگ «!Hello» در خروجی چاپ خواهد شد.
در ادامه فانکشن مذکور را فراخوانی میکنیم:
greet();
greet.locale = 'fr';
greet();
به طور کلی، نتیجۀ حاصل از اجرای دستورات فوق بدین ترتیب خواهد بود:
Hello!
Bonjour!
همانطور که در کد فوق مشاهده میکنید، فانکشن ()greet
در ابتدا بدون استرینگ ورودی فراخوانی شده است که منجر به اجرای دستور مربوط به else
شده و استرینگ «!Hello» در خروجی چاپ میشود و در ادامه استرینگ ورودیِ «fr» را به آبجکت locale
از فانکشن ()greet
اختصاص دادهایم که منجر به چاپ استرینگ «!Bonjour» خواهد شد.
امکان تگگذاری Template Literals
Template Literals در نسخۀ ES6 به این زبان افزوده شدند و با علائم به اصطلاح بَککوتیشن یا ``
نشان داده میشوند که این امکان را در اختیار دولوپرها قرار میدهند تا استرینگ مد نظر خود را دقیقاً به همان صورت ورودی در خروجی چاپ کرده و همچنین قابلیت شناسایی و پردازش دستور مد نظر با بهکارگیری علائم {}$
را برای ایشان فراهم میکنند به طوری که داریم:
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
در کد بالا دو متغیر تحت عناوین a
و b
با مقادیر اولیۀ 5 و 10 تعریف کرده و در ادامه گفتهایم استرینگ فوق در خروجی چاپ شود که میبینیم به سادگی بخشی از استرینگ مد نظر در سطر بعد چاپ شده و دستورات مربوط به دو متغیر نیز با بهکارگیری بککوتیشنها و همچنین علائم {}$
شناسایی و اجرا میشوند و در نهایت خروجی حاصل از اجرای این دستور به ترتیب زیر خواهد بود:
Fifteen is 15 and
not 20.
همانطور که میبینید، استرینگ مد نظر به همان شکل ورودی در دو سطر مجزا پردازش شده و در خروجی چاپ میشود مضاف بر اینکه دستورات داخل علائم {}$
شناسایی شده و روی دو متغیر مذکور اِعمال شدهاند.
همچنین لازم به یادآوری است که در نسخۀ جدید زبان برنامهنویسی جاوااسکریپت قابلیت تگگذاری روی به اصطلاح Template Literal نیز فراهم شده است که این امکان را در اختیار دولوپرها قرار میدهد تا بتوانند یکسری پردازشها روی استرینگ مد نظر و با استفاده از فانکشنی تحت عنوان تگ مذکور اِعمال کنند که برای این منظور مثال زیر را مد نظر قرار دادهایم:
function highlight(strings, ...values) {
let result = ''
strings.forEach((str, i) => {
result += str
if (values[i]) {
result += `<mark>${values[i]}</mark>`
}
})
return result
}
const author = 'Henry Avery'
const statement = `I am a man of fortune & I must seek my fortune`
const quote = highlight `${author} once said, ${statement}`
console.log(quote)
در این کد فانکشنی تحت عنوان ()highlight
تعریف کردهایم که دو آرگومان ورودی به نامهای strings
و values
دارد که در ادامه کاربرد هر یک را به ترتیب بررسی میکنیم:
- متغیر strings
قرار است تا آرایهای از استرینگهای مد نظر برای چاپ در خروجی را ذخیره سازد.
- متغیر values
مجموعهای از آرگومانهای ورودی را نگاهداری میکند که به عنوان استرینگ ورودی به فانکشن میدهیم و به آرایۀ فوقالذکر افزوده میشوند تا در استرینگ خروجی جایگذاری شده و چاپ شوند.
در واقع، طبق دستورات فوق در حال حاضر پارامترهای ورودی به فانکنشن ()highlight
بدین صورت میباشند:
highlight([' ', 'once said', ' '], 'I am a man of fortune & I must seek my fortune', 'Henry Avery')
پارامتر اول آرایهای از استرینگهای مد نظر برای چاپ در خروجی است که اِلِمان اول و سوم در حال حاضر خالی بوده و در ادامه دو استرینگ فوق را به عنوان ورودی به آن پاس دادهایم که میخواهیم به ترتیب به جای علائم {}$
جایگذاری شده و در خروجی چاپ شوند.
در تفسیر کد فوق باید بگوییم که فانکشن ()highlight
را بدین صورت تعریف کردهایم که در ابتدا متغیری به نام result
تعریف کرده و مقدار اولیۀ آن را یک استرینگ خالی قرار دادهایم و در ادامه به ازای هر یک از عناصر آرایۀ strings
متغیری به نام i
تعریف کردهایم تا بتوانیم هر یک از عناصر آرایۀ مذکور تحت عنوان str
را پیمایش کنیم که بدین ترتیب هر یک از آنها را برداشته و به متغیر result
اضافه میکنیم و گفتهایم تا زمانی که اِلِمانی داخل متغیر values
(استرینگهای ورودی به تابع مد نظر) وجود داشته باشد، آنها را به ترتیب برداشته و در متغیر result
داخل تگهای <mark></mark>
جایگذاری کند و در نهایت مقادیر استرینگهای ورودی و استرینگ تعریفشده در متغیر strings
با یکدیگر کانکت شده و استرینگ نهایی در خروجی ریترن میشود.
به منظور فراخواننی فانکشن ()highlight
دو متغیر تحت عناوین author
و statement
تعریف کرده و استرینگهای فوق را به آنها اختصاص دادهایم و در ادامه متغیری دیگر تحت عنوان quote
تعریف میکنیم که قرار است تا نتیجۀ حاصل از اجرای فانکشن ()highlight
در آن نگاهداری شود که بدین ترتیب فانکشن ()highlight
فراخوانی شده و در آن گفتهایم هر یک از استرینگهای زیر به ترتیب در آرایۀ strings
نگاهداری شوند:
' ' //null string
'once said'
' ' //null string
در ادامه هر یک از استرینگهای موجود در متغیرهای author
و statement
به متغیر values
داده شده و به ترتیب به جای دستورهای {author}$
و {statement}$
جایگذاری میشوند و در نهایت استرینگ ذخیرهشده در متغیر quote
چاپ میشود که در خروجی استرینگ زیر را خواهیم داشت:
<mark> Henry Avery </mark> once said, <mark>I am a man of fortune & I must seek my fortune</mark>
همانطور که مشاهده میکنید، استرینگهای ورودی داخل تگهای <mark></mark>
قرار گرفته و با استرینگ تعریفشده کانکت شدهاند.
کیوردهای get و set
دسترسی به پراپرتیهای مربوط به آبجکتهای تعریفشده در زبان جاوااسکریپت بسیار ساده است. برای مثال، اگر آبجکتی فرضی تحت عنوان user
داشته باشیم که یکی از پراپرتیهای آن را age
تعریف کنیم، بدین ترتیب دسترسی به پراپرتی مذکور با دستور user.age
امکانپذیر خواهد بود که مقدار اختصاصیافته به پراپرتی مد نظر را به دست خواهیم آورد یا اگر چنانچه آبجکت user
یک پراپرتی تحت عنوان age
نداشته باشد، مقدار undefined
در خروجی ریترن خواهد شد.
فیچرهایی تحت عنوان get
و set
در جاوااسکریپت این امکان را برای دولوپرها فراهم میکنند تا بتوانند به ترتیب یک فانکشن به اصطلاح Getter تعریف کرده و مقادیر مد نظر خود از آبجکت مذکور را در خروجی ریترن کنند و همچنین با تعریف یک فانکشن Setter نیز میتوان یکسری پراپرتی جدید برای آبجکت مذکور تعریف کرده و مقادیری منحصربهفرد برای آنها به اصطلاح سِت کرد:
const user = {
firstName: 'Ali',
lastName: 'Azad',
get fullName() {
return this.firstName + ' ' + this.lastName
},
set age(value) {
if (isNaN(value)) throw Error('Age has to be a number')
this.tmpAge = Number(value)
},
get age() {
return this.tmpAge
}
}
همانطور که در کد فوق میبینید، آبجکتی تحت عنوان user
ایجاد کرده و در ادامه یکسری پراپرتی به نامهای firstName
و lastName
برای آن تعریف کردهایم که به ترتیب نام و نام خانوادگی کاربر را نگاهداری میکنند و در ادامه با بهکارگیری کیورد get
فانکشنی تحت عنوان ()fullName
تعریف میکنیم که خود در نقش یک پراپرتی برای آبجکت مذکور خواهد بود و بدین ترتیب گفتهایم مقادیری را نگاهداری کند که مربوط به پراپرتیهای firstName
و lastName
هستند و این مقادیر با قرار دادن یک فاصله مابین آنها با یکدیگر کانکت شده و به عنوان مقدار پراپرتی fullName
در خروجی ریترن شود که از این پس مقدار پراپرتی fullName
برابر با نام و نام خانوادگی کاربر خواهد بود.
حال قصد داریم تا پراپرتی جدیدی به آبجکت user
تحت عنوان age
بیفزاییم که برای این منظور فانکشنی تحت عنوان ()age
با بهکارگیری کیورد set
تعریف میکنیم که خود در نقش پراپرتی مذکور میباشد و یک آرگومان ورودی تحت عنوان value
به آن داده و در ادامه گفتهایم اگر چنانچه مقدار متغیر value
(پارامتر ورودی به این فانکشن) از نوع عدد نبود، اروری در قالب استرینگ «Age has to be a number» در خروجی چاپ شود و در ادامه گفتهایم مقدار پارامتر ورودی که حتماً از نوع عدد میباشد را به متغیری تحت عنوان tmpAge
اختصاص دهد که در سطر بعد با بهکارگیری کیورد get
گفتهایم فانکشن ()age
که به عنوان یک پراپرتی تحت عنوان age
برای آبجکت user
میباشد، مقدار ذخیرهشده در متغیر tmpAge
را ریترن کند.
در نهایت برای تست کد فوق دستورات زیر را بدین صورت مینویسیم:
console.log(user.fullName)
user.firstName = 'Morteza'
console.log(user.fullName)
user.age = '27'
console.log(user.age)
user.age = 'Twenty Seven'
در دستور اول گفتهایم مقدار پراپرتی fullName
از آبجکت user
در خروجی چاپ شود که مفسر جاوااسکریپت به دنبال پراپرتی مذکور در آبجکت user
میگردد که در فانکشن ()fullName
از نوع get
گفتهایم مقدار معادل برای این پراپرتی، استرینگ کانکتشده از مقادیر مربوط به دو پراپرتی firstName
و lastName
میباشد و بنابراین عبارت زیر در خروجی چاپ میشود:
Ali Azad
دستور سطر دوم مقدار پراپرتی firstName
از آبجکت user
را به استرینگ «Morteza» تغییر میدهد که بدین ترتیب عبارت «Morteza Azad» به پراپرتی fullName
اختصاص یافته و دستور سطر سوم استرینگ زیر را در خروجی چاپ میکند:
Morteza Azad
در دستور سطر چهارم نیز گفتهایم عدد 27 به پراپرتی جدید age
اختصاص یافته و در ادامه مقدار آن در خروجی چاپ میشود و در سطر آخر نیز استرینگ «Twenty Seven» را به پراپرتی age
اختصاص میدهیم که با توجه به شرط مطرحشده در فانکشن مربوط به این پراپرتی تحت عنوان ()age
گفتهایم مقدار ورودی برای این پراپرتی حتماً باید از نوع عدد باشد و از همین روی اجرای دستور فوق منجر به ایجاد اروری در قالب استرینگ زیر میشود:
Uncaught Error: Age has to be a number
بدین ترتیب با استفاده از قابلیت به اصطلاح set
و get
در این زبان میتوانیم پراپرتیهای مد نظر از آبجکتی را در خروجی ریترن کرده و همچنین در صورت نیاز یکسری پراپرتی برای آبجکت خود تعریف کنیم.
اپراتور Comma
اپراتور کاما با علامت ,
در زبان برنامهنویسی جاوااسکریپت یکسری فیچرهایی در اختیار دولوپرها قرار میدهد که در ادامه هر یک از آنها را بررسی میکنیم.
فیچر اول بدین صورت است که با استفاده از کاما میتوانیم نتیجۀ حاصل از اجرای چند دستور متفاوت را به یک متغیر منتسب کنیم که در نهایت نتیجۀ ریترنشده از اجرای دستور آخر در متغیر مذکور نگاهداری خواهد شد به طوری که در یک حالت کلی داریم:
let result = expression1, expression2, ... expression N
در شبهکد فوق نتیجۀ ریترنشده از اجرای دستور شمارۀ N در متغیری به نام result
نگاهداری میشود.
قابلیت بعدی برای اپراتور کاما جدا کردن یکسری به اصطلاح Statement مربوط به حلقۀ تکرار for
میباشد که یک مثال از آن در ادامه بررسی میشود:
for (var a = 0, b = 10; a <= 10; a++, b--)
در دستور فوق گفتهایم به ازای دو متغیر a
و b
با مقادیر اولیۀ 0 و 10 دستورات فرضی داخل بلوک for
اجرا شوند و در هر مرتبه اجرای آنها هم یک واحد به متغیر a
اضافه شده و هم یک واحد از مقدار متغیر b
کم شود و اجرای دستورات داخل حلقه نیز تا زمانی ادامه یابد که مقدار متغیر a
کوچکتر یا مساوی با عدد 10 میشود.
فیچر دیگری در مورد علامت ,
بهکارگیری آن برای جدا کردن دستوراتی است که میخواهیم به صورت خلاصه و در یک سطر نوشته شوند که برای مثال داریم:
function getNextValue() {
return counter++, console.log(counter), counter
}
در این کد فانکشنی فرضی تحت عنوان ()getNextValue
تعریف کردهایم که در صورت اجرا مقدار مربوط به متغیر فرضی counter
را یک واحد افزایش داده و در خروجی ریترن میکند و در ادامه مقدار آن را در خروجی چاپ میکند که دستور سوم نیز مجدداً منجر به ریترن شدن مقدار موجود در متغیر counter
در خروجی میشود که اکنون یک واحد افزایش پیدا کرده است.
اپراتور Plus
اپراتور +
پیش از استرینگ مد نظر آمده و به منظور تبدیل دیتا تایپ استرینگ به دیتا تایپ عددی مورد استفاده قرار میگیرد بدین صورت که اگر قبل از هرگونه استرینگی ذکر شود، دیتا تایپ آن به نوع دادۀ عددی تغییر مییابد:
typeof('9.11')
typeof(+'9.11')
در دستور سطر اول با بهکارگیری کیورد typeof
نوع دادۀ عبارت '9.11' را در خروجی ریترن میکنیم که string
است اما همانطور که میبینید در دستور سطر بعد با استفاده از اپراتور +
نوع دادۀ استرینگ مذکور را به عدد تغییر دادهایم و نتیجۀ ریترن شده از آن عبارت number
خواهد بود.
اپراتور Double Bang
در زبان برنامهنویسی جاوااسکریپت اپراتور !
به NOT منطقی اشاره میکند و مقدار بولین برای عبارت مد نظر را معکوس میکند که با بهکارگیری آن مقادیر بولین true
به false
و برعکس تبدیل میشوند و از همین روی اپراتور !!
که تحت عنوان Double Bang نیز شناخته میشود به معنای معکوس کردن اثر NOT منطقی بوده و بدین صورت عمل میکند که در ابتدا مقدار بولین عبارت مد نظر را معکوس کرده و در ادامه مقدار حاصل را مجدداً معکوس میکند. برای مثال در دستور زیر داریم:
const x = '';
!!x;
در کد فوق متغیری به نام x
تعریف کرده و مقدار استرینگ خالی را به آن دادهایم و از آنجایی که مقدار بولین برای یک استرینگ خالی برابر false
میباشد، در ادامه گفتهایم مقدار بولین برای این متغیر دو مرتبه معکوس شود که در ابتدا منجر به true
شدن متغیر x
و در مرحلۀ بعد منجر به false
شدن مقدار بولین آن میگردد که در نهایت عبارت false
برای متغیر مذکور در خروجی ریترن میشود. به عنوان یک مثال دیگر داریم:
!!null
لازم به یادآوری است که مقدار بولین برای کیورد null
برابر با false
میباشد که در طی دو مرتبه معکوسسازی آن ابتدا به مقدار true
و در مرحلۀ بعد مجدداً به مقدار بولین false
تغییر مییابد.
قابلیت لیبلگذاری Statements
در یکی دیگر از فیچرهای جدید زبان برنامهنویسی جاوااسکریپت امکانی برای دولوپرها فراهم شده است که در آن میتوان برخی بلوکهای کد و یا حلقههای تکرار مد نظر خود را به اصطلاح لِیبلگذاری کرد که بدین ترتیب با بهکارگیری دستورهای break
و یا continue
به قطعه کد مد نظر دسترسی داریم و به منظور تسهیل هندل کردن حلقههای تودرتو مورد استفاده قرار میگیرد که در همین راستا مثال زیر را در ادامه بررسی میکنیم:
First: for (var i = 0; i < 3; i++) {
Second: for (var j = 0; j < 3; j++) {
if (i === 1) continue First;
if (j === 1) break Second;
console.log(i);
console.log(j);
}
}
در کد فوق لیبلی تحت عنوان First
برای حلقۀ اول و لیبلی دیگر تحت عنوان Second
برای حلقۀ دوم در نظر گرفتهایم و در ادامه گفتهایم هر دو حلقه سه مرتبه اجرا شوند که مراحل مذکور بدین صورت خواهند بود:
در ابتدا مقدار متغیر i
و j
برابر با 0 بوده و هیچ یک از دستورات شرطی اول و دوم برقرار نیستند که در مرحلۀ اول دو عدد 0 در خروجی چاپ خواهند شد. در مرحلۀ بعد مقدار متغیر i
همچنان 0 بوده و حلقۀ داخلی یک واحد متغیر j
را افزایش میدهد که اکنون مقادیر زیر را برای دو متغیر i
و j
داریم:
i = 0
j = 1
در نتیجه شرط دوم برقرار شده و با اجرای دستور ;break Second
مفسر از حلقۀ داخلی خارج میشود و به اجرای حلقۀ First
میپردازد و بدین ترتیب مقدار متغیر i
یک واحد افزایش یافته و شرط اول برقرار میشود و با اجرای دستور ;continue First
گفتهایم چنانچه مقدار متغیر i
برابر با عدد 1 باشد، حلقه از ابتدا اجرا شود بدین معنی که ادامۀ دستور اجرا نشده و مفسر از ابتدا کد را اجرا میکند و از همین روی عدد 1 تحت هیچ عنوان در خروجی چاپ نمیشود که اکنون مقادیر دو متغیر i
و j
به ترتیب زیر خواهند بود:
i = 1
j = 0
که در مرحلۀ بعد مجدداً حلقۀ First
مقدار متغیر i
را یک واحد افزایش میدهد و در نتیجه مقدار دو متغیر i
و j
به ترتیب زیر خواهند بود:
i = 2
j = 0
در ادامه شرط اول و دوم چک میشود که هیچ یک برقرار نبوده و مفسر به سراغ اجرای سطرهای بعدی میرود که در این مرحله دستورات مربوط به چاپ مقادیر دو متغیر i
و j
اجرا شده و دو عدد 2 و 0 به ترتیب در خروجی چاپ میشوند. به طور کلی خروجی حاصل به صورت زیر خواهد بود:
0
0
2
0
همانطور که میبینید مقدار عدد 1 از متغیر i
هرگز چاپ نشده و حلقۀ Second
نیز تنها یک مرتبه اجرا شده و در مرحلۀ بعد مفسر جاوااسکریپت از حلقۀ مذکور خارج میشود که بدین ترتیب مقدار متغیر j
همچنان 0 باقی میماند.
جمعبندی
در این مقاله به بیان برخی از فیچرهای زبان برنامهنویسی جاوااسکریپت و بررسی کاربردهای آنها پرداختیم که مسلماً بخش کوچکی از قابلیتهای این زبان انعطافپذیر را شامل میشود. همچنین در صورت تمایل به آشنایی با دیگر مقالات مرتبط با این زبان میتوانید با دنبال کردن تگ #جاوااسکریپت به اطلاعات بیشتری دست یابید.