۱۴ ژوئیه ۲۰۲۳

انشعاب شرطی: if، '?'

بعضی اوقات، ما نیاز داریم که کارهای مختلفی را بر اساس شرایط مختلف انجام دهیم.

برای انجام این کار، ما از دستور if و عملگر شرطی (سه‌تایی) که ما برای سادگی به عنوان عملگر «علامت سوال» ? به آن اشاره خواهیم کرد، استفاده می‌کنیم.

دستور “if”

دستور if(...) شرطی را در پرانتز ارزیابی می‌کند و اگر نتیجه آن true باشد، یک بلوک کد را اجرا می‌کند.

برای مثال:

let year = prompt('در چه سالی مشخصات ECMAScript-2015 منتشر شد؟', '');

if (year == 2015) alert( 'درست گفتید!' );

در مثال بالا، شرط یک بررسی برابری ساده است (year == 2015) اما می‌تواند خیلی پیچیده‌تر باشد.

اگر ما بخواهیم بیشتر از یک دستور را اجرا کنیم، باید کدمان را درون آکولاد قرار دهیم:

if (year == 2015) {
  alert( "درست است!" );
  alert( "شما باهوش هستید!" );
}

ما پیشنهاد می‌کنیم که کدتان را هر بار که از دستور if استفاده می‌کنید، درون آکولاد {} بگذارید حتی اگر تنها یک دستور برای اجرا کردن دارید. انجام دادن این کار خوانایی را افزایش می‌دهد.

تبدیل به بولین

دستور if (…) عبارت درون پرانتز را ارزیابی می‌کند و نتیجه را به بولین تبدیل می‌کند.

بیایید قوانین تبدیل را از فصل تبدیل نوع داده به یاد بیاوریم:

  • عدد 0، یک رشته خالی ""، null، undefined و NaN همگی به false تبدیل می‌شوند. به همین دلیل به آنها مقدارهای “falsy” می‌گویند.
  • مقدارهای دیگر به true تبدیل می‌شوند پس “truthy” نامیده می‌شوند.

پس کد زیر با این شرط هیچگاه اجرا نمی‌شود:

if (0) { // است falsy ،مقدار 0
  ...
}

…و درون با این شرط – همیشه اجرا می‌شود:

if (1) { // است truthy ،مقدار 1
  ...
}

همچنین ما می‌توانیم یک مقدار بولین که از قبل ارزیابی شده است را به if بدهیم، مانند اینجا:

let cond = (year == 2015); // false است یا true برابری بعد از ارزیابی یا

if (cond) {
  ...
}

عبارت “else”

دستور if ممکن است شامل یک بلوک اختیاری else هم شود. این بلوک زمانی که شرط falsy باشد اجرا می‌شود.

برای مثال:

let year = prompt('در چه سالی مشخصات ECMAScript-2015 منتشر شد؟', '');

if (year == 2015) {
  alert( 'شما درست حدس زدید!' );
} else {
  alert( 'چطور اشتباه گفتید؟' ); // هر مقداری به جز 2015
}

چند شرط: “else if”

گاهی اوقات، ما می‌خواهیم که چند نوع از یک شرط را آزمایش کنیم. عبارت else if به امکان همچین کاری را می‌دهد.

برای مثال:

let year = prompt('در چه سالی مشخصات ECMAScript-2015 منتشر شد؟', '');

if (year < 2015) {
  alert( 'کم گفتید...' );
} else if (year > 2015) {
  alert( 'زیاد گفتید' );
} else {
  alert( 'دقیقا!' );
}

در کد بالا، جاوااسکریپت در ابتدا year < 2015 را بررسی می‌کند. اگر falsy باشد، به شرط بعدی year > 2015 می‌رود. اگر آن هم falsy باشد، alert آخر نمایش داده می‌شود.

بلوک‌های else if بیشتری هم می‌تواند وجود داشته باشد. else آخری اختیاری است.

عملگر سه‌گانه ‘?’

گاهی اوقات، ما نیاز داریم که بر اساس شرطی، یک متغیر را مقداردهی کنیم.

برای مثال:

let accessAllowed;
let age = prompt('چند سال دارید؟', '');

if (age > 18) {
  accessAllowed = true;
} else {
  accessAllowed = false;
}

alert(accessAllowed);

عملگر «سه‌گانه» یا «علامت سوال» به ما اجازه انجام این کار با روشی کوتاه‌تر و ساده‌تر را می‌دهد.

این عملگر با یک علامت سوال ? نمایش داده می‌شود. عبارت رسمی «سه‌گانه» به معنی این است که عملگر سه عملوند دارد. در واقع این عملگر، تنها عملگری در جاوااسکریپت است که این تعداد عملوند دارد.

سینتکس آن:

let result = condition ? value1 : value2;

بعد از اینکه condition ارزیابی شود: اگر truthy باشد سپس value1 برگردانده می‌شود، در غیر این صورت – value2.

برای مثال:

let accessAllowed = (age > 18) ? true : false;

از لحاظ فنی، ما می‌توانیم پرانتز دور age > 18 را حذف کنیم. عملگر علامت سوال اولویت پایینی دارد پس بعد از مقایسه > اجرا می‌شود.

این مثال کار یکسانی با مثال قبل انجام می‌دهد:

// در هر صورت اول اجرا می‌شود "age > 18" عملگر مقایسه
// (نیازی نیست که آن را درون پرانتز بگذاریم)
let accessAllowed = age > 18 ? true : false;

اما پرانتزها کد را خواناتر می‌کنند، پس ما پیشنهاد می‌کنیم که از آنها استفاده کنید.

لطفاً توجه کنید:

در مثال بالا، شما می‌توانید از عملگر علامت سوال استفاده نکنید چون خود مقایسه true/false برمی‌گرداند.

// نتیجه یکسان است
let accessAllowed = age > 18;

بیشتر از یک علامت سوال ‘?’

توالی از عملگرهای علامت سوال ? می‌تواند مقداری که به بیشتر از یک شرط بستگی دارد را برگرداند.

برای مثال:

let age = prompt('سن شما؟', 18);

let message = (age < 3) ? 'سلام کوچولو!' :
  (age < 18) ? 'سلام!' :
  (age < 100) ? 'درود!' :
  'چه سن غیر معمولی!';

alert( message );

ممکن است در نگاه اول فهمیدن اینکه چه چیزی در حال رخ دادن است سخت باشد. اما بعد از یک نگاه دقیق‌تر، متوجه می‌شویم که فقط یک توالی معمولی از آزمایش‌ها است:

  1. اولین علامت سوال بررسی می‌کند که آیا age < 3.
  2. اگر درست باشد – 'سلام کوچولو!' برگردانده می‌شود. در غیر این صورت به عبارت بعد از دو نقطه “:” می‌رود و age < 18 را بررسی می‌کند
  3. اگر درست باشد – 'سلام!' را برمی‌گرداند. در غیر این صورت، به عبارت بعد از دو نقطه بعدی “:” می‌رود و age < 100 را بررسی می‌کند.
  4. اگر درست باشد – 'درود!' را برمی‌گرداند. در غیر این صورت، به عبارت بعد از آخرین “:” می‌رود و 'چه سن غیر معمولی!' را برمی‌گرداند.

اگر از if..else استفاده می‌شد، اینگونه بنظر می‌رسید:

if (age < 3) {
  message = 'سلام کوچولو!';
} else if (age < 18) {
  message = 'سلام!';
} else if (age < 100) {
  message = 'درود!';
} else {
  message = 'چه سن غیر معمولی!';
}

استفاده غیر سنتی از ‘?’

بعضی اوقات علامت سوال ? به عنوان جایگزینی برای if استفاده می‌شود:

let company = prompt('کدام کمپانی جاوااسکریپت را ساخت؟', '');

(company == 'Netscape') ?
   alert('درست گفتید!') : alert('اشتباه گفتید.');

با توجه به شرط company == 'Netscape'، عبارت اول یا دوم بعد از ? اجرا می‌شود و یک alert را نمایش می‌دهد.

اینجا ما یک نتیجه را برابر با یک متغیر قرار نمی‌دهیم. به جای آن، ما کد متفاوتی را بسته به شرایط اجرا می‌کنیم.

استفاده از عملگر علامت سوال به این روش اصلا پیشنهاد نمی‌شود.

این روش نسبت به دستور یکسان if کوتاه‌تر است، که بعضی از برنامه‌نویسان را جذب می‌کند. اما خوانایی کمتری دارد.

اینجا همان کد را با استفاده از if برای مقایسه آورده‌ایم:

let company = prompt('کدام کمپانی جاوااسکریپت را ساخت؟', '');

if (company == 'Netscape') {
  alert('درست گفتید!');
} else {
  alert('اشتباه گفتید.');
}

چشمان ما کد را به صورت عمودی اسکن می‌کنند. بلوک‌های کد که در چند خط نوشته شده‌اند نسبت به یک مجموعه دستور طولانی و افقی، برای فهمیدن راحت‌تر هستند.

هدف عملگر علامت سوال ? این است که یک مقدار یا مقدار دیگری را با توجه به شرایط آن برگرداند. لطفا دقیقا با همین هدف از آن استفاده کنید. زمانی که نیاز دارید شاخه‌های متفاوتی از کد را اجرا کنید از if استفاده کنید.

تمارین

اهمیت: 5

آیا alert اجرا می‌شود؟

if ("0") {
  alert( 'سلام' );
}

بله اجرا می‌شود.

هر رشته به جز رشته خالی ("0" خالی نیست!) از نظر منطقی true ارزیابی می‌شود.

می‌توانیم این تکه کد را اجرا کنیم و مورد بالا را بررسی کنیم:

if ("0") {
  alert( 'سلام' );
}
اهمیت: 2

با استفاده از ساختار if..else، کدی بنویسید که بپرسد: ‘What is the “official” name of JavaScript?’

اگر بازدیدکننده “ECMAScript” را وارد کند، سپس پیام “Right!” را نشان دهید، در غیر این صورت این پیام را نشان دهید: “You don’t know? ECMAScript!”

دمو درون یک پنجره جدید

<!DOCTYPE html>
<html>

<body>
  <script>
    'use strict';

    let value = prompt('What is the "official" name of JavaScript?', '');

    if (value == 'ECMAScript') {
      alert('Right!');
    } else {
      alert("You don't know? ECMAScript!");
    }
  </script>


</body>

</html>
اهمیت: 2

با استفاده از if..else، کدی بنویسید که با استفاده از prompt یک عدد می‌گیرد و سپس با alert یکی از اینها را نشان می‌دهد:

  • 1، اگر مقدار بزرگ‌تر از صفر بود،
  • -1، اگر کمتر از صفر بود،
  • 0، اگر برابر با صفر بود.

در این تکلیف ما فرض می‌کنیم که ورودی همیشه یک عدد است.

دمو درون یک پنجره جدید

let value = prompt('یک عدد وارد کنید', 0);

if (value > 0) {
  alert( 1 );
} else if (value < 0) {
  alert( -1 );
} else {
  alert( 0 );
}
اهمیت: 5

این if را با استفاده از عملگر شرطی بازنویسی کنید:

let result;

if (a + b < 4) {
  result = 'Below';
} else {
  result = 'Over';
}
let result = (a + b < 4) ? 'Below' : 'Over';
اهمیت: 5

با استفاده از چند عملگر سه‌گانه '?' دستور if..else را بازنویسی کنید.

برای خوانایی بهتر، پیشنهاد می‌شود کد را در چند خط بنویسید.

let message;

if (login == 'کارمند') {
  message = 'سلام';
} else if (login == 'مدیر') {
  message = 'درود';
} else if (login == '') {
  message = 'وارد سیستم نشدید';
} else {
  message = '';
}
let message = (login == 'کارمند') ? 'سلام' :
  (login == 'مدیر') ? 'درود' :
  (login == '') ? 'به سیستم وارد نشدید' :
  '';
نقشه آموزش