بسیاری از توسعهدهندگان وب از React به عنوان کتابخانه اصلی خود برای ساخت کامپوننتهای رابط کاربری وبسایت خود استفاده میکنند. React یکی از محبوبترین فریمورکها برای توسعه وب است و به طور کامل با جاوااسکریپت نوشته شده است. بنابراین از بسیاری از مفاهیم آن که قبلا و در نسخه ES6 جاوااسکریپت معرفی شده بودند استفاده میکند. در نتیجه درک این مفاهیم برای هر کسی که قصد یادگیری React را دارد، مهم است.
در این مقاله قصد داریم تا هفت مفهوم مهم جاوااسکریپت که یک توسعهدهنده قبل از یادگیری React باید آن را بداند، با مثالهای دقیق بررسی کنیم.
ما در جاوااسکریپت از دستورات شرطی استفاده میکنیم تا مشخص کنیم که در صورت true بودن شرایط خاص، یک بلاک کد باید اجرا شود. عبارات شرطی در رندر شرطی کامپوننتهای UI در React مفید هستند. آنها به ما اجازه میدهند تا UI خود را بر اساس شرایط خاصی رندر کنیم.
اولین چیزی که در مورد دستورات شرطی باید بدانیم این است که چگونه باید از دستور if … else استفاده کنیم. فرض کنید دو عدد داریم، میخواهیم کدی بنویسیم که اگر عدد دوم بزرگتر از عدد اول باشد، این دو عدد را با هم جمع کرده و در غیر این صورت آنها را از هم کم کند. در اینجا با استفاده از عبارت if … else کد مورد نظر ما به شکل زیر میباشد:
if (a < b) { let output = a + b; } else { let output = a - b; }
در عبارت if… else، میتوانیم به جای نوشتن ifهای متعدد، از else … if استفاده کنیم. else…if این امکان را برای ما فراهم میکند تا چند شرط را با هم بنویسیم. اگر شرط اول false باشد، شرط جدید را برای بررسی مشخص میکند.
if (a < b) { let output = a + b; } else if (a > b) { let output = a - b; } else { let output = a * b; }
در کد بالا مثال قبلی را در قالب یک عبارت else…if نوشتهایم. اگر شرط قبلی false باشد، else…if شرط بزرگتر بودن a از b را بررسی میکند.
عملگر ternary روشی مختصرتر برای نوشتن عبارت if… else است. این عملگر به سه عملوند نیاز دارد: ابتدا یک شرط و به دنبال یک علامت سوال (؟
)، سپس یک عبارت که در صورت true بودن شرط اجرا میشود و سپس یک دونقطه (:
) و در نهایت عبارتی که اگر شرط false باشد اجرا میشود.
اگر بخواهیم مثال if … else بالا را با استفاده از یک عملگر ternary بازنویسی کنیم، باید به شکل زیر باشد:
(a < b) ? a + b : a - b;
(a <b) عبارت شرط است، ? شرط را ارزیابی میکند و اگر true باشد مقدار a + b و اگر false باشد مقدار a – b را برمیگرداند.
این پنج خط کد از مثال قبلی است که فقط در یک خط نوشته شده است. اما اگر بخواهیم else…if را در کد عملگر ternary خود داشته باشیم باید به شکل زیر عمل کنیم:
(a < b) ? a + b : (a > b) ? a - b : a * b;
در کد بالا، ? شرط (a < b) را ارزیابی میکند و اگر true باشد مقدار a + b را برمیگرداند. اما اگر false باشد شرط دوم (a > b) را ارزیابی میکند و اگر true باشد مقدار a – b و در غیر این صورت مقدار a * b را برمیگرداند.
این کد را هم فقط در یک خط نوشتیم. اما برای این که کد خواناتری داشته باشیم میتوانیم آن را به چند خط تقسیم کنیم.
در مثال زیر میبینیم که چگونه میتوانیم با قرار دادن شرط و عبارت return در یک خط، کدی که داریم را به چند خط تقسیم کنیم:
(a < b) ? a + b : (a > b) ? a - b : a * b;
Destructuring در جاوااسکریپت زمانی انجام میشود که مقادیر آرایهها یا ویژگیها را از آبجکتها جدا میکنیم و آنها را به یک متغیر اختصاص میدهیم.
این مفهوم extract کردن دادهها از آرایهها و آبجکتها را آسانتر میکند و در مفاهیم React مانند useState قابل استفاده است.
Array destructuring برای extract کردن دادهها از یک آرایه استفاده میشود.
در مثال زیر، آرایه newArray
را به دو صورت destruct میکنیم. راه اول این است که آرایهای حاوی متغیرهایی که میخواهیم به مقادیر آرایه خود اختصاص دهیم را تعریف کنیم و آن را به متغیر newArray اختصاص دهیم. راه دوم این است که آرایهای از متغیرها را به آرایهای که حاوی مقادیری است که میخواهیم destruct کنیم، تخصیص دهیم.
let newArray = ["Musab", "I", "Handsome"]; let [noun, pronoun, adjective] = newArray; // The above can also be rewritten as this: let [noun, pronoun, adjective] = ["Musab", "I", "Handsome"]; console.log(noun); console.log(pronoun);
ما میتوانیم یک یا چند مقدار را با قرار دادن کاما در جای آنها skip کنیم.
let newArray = [a, b, c, d, e]; let [firstLetter, , , ,lastLetter] = [a, b, c, d, e];
Object destructuring شبیه array destructuring است، اما در آبجکتها ما فقط keyها را destruct میکنیم. در مثال زیر، personObject
با تعریف یک آبجکت حاوی ویژگیهای personObject و انتساب آن به personObject دچار destruct شد.
let personObject = { name: "David", age: 18, height: "6ft 5in", gender: "male", } let {name, age, height, gender} = personObject console.log(name, age, height, gender);
اکنون میتوانیم بدون فراخوانی آبجکت به مقادیر هر یک از keyها دسترسی داشته باشیم.
همچنین میتوانیم هر یک از keyهای destruct شده را به متغیرهای جدید اختصاص دهید.
let personObject = { name: "David", age: 18, height: "6ft 5in", gender: "male", } let {name: personName, age: personAge, height: personHeight, gender: personGender} = personObject; console.log(personName, personAge, personHeight, personGender);
Template literalها همانند رشتهها که داخل ""
قرار میگیرند، در بکتیکها قرار میگیرند. آنها به ما این امکان را میدهند تا رشتههای چند خطی را ذخیره نماییم، همچنین میتوانیم در کنار رشتهها از عبارتهایی که داریم هم استفاده کنیم.
مثال زیر یک template literal پایه را نشان میدهد.
let basic = `I write codes`
میتوانیم یک template literal بنویسیم که رشتههای چند خطی را مانند زیر ذخیره میکند:
let multiLine = `I write codes I debug codes`;
همینطور میتوانیم از علامت $
و {}
برای به کار بردن عبارات در داخل template literal استفاده کنیم.
در مثال زیر، تابع myName
با استفاده از template literal در متغیر display مورد استفاده قرار گرفته است:
function myName(Musab, Habeeb) { alert("Musab Habeeb"); } let display = `This displays my name ${myName()}`
یک آبجکت این امکان را به ما میدهد تا بتوانیم مجموعهای از دادهها را ذخیره کنیم. دادهها در داخل {}
و در قالب جفت key-value ذخیره میشوند.
در مثال زیر یک آبجکت به نام myObject
ایجاد میکنیم و سه key با مقادیر مربوطه به آن میدهیم.
let myObject = { name: Musab, number: 12, developer: [true, "David", 1] }
ما میتوانیم از دو طریق به مقادیری که به هر key در آیجکت تعلق دارند دسترسی داشته باشیم:
[]
)در مثال زیر با استفاده از علامت براکت به ویژگی name و با استفاده از علامت نقطه به ویژگی number دسترسی داریم.
let myObject = { name: "Musab", number: 12, developer: [true, "David", 1] } console.log(myObject["name"]); console.log(myObject.number);
keyهای آبجکت باید به صورت رشتهای باشند. زیرا اگر اینطور نباشند، با استفاده از علامت نقطه نمیتوانیم به آنها دسترسی داشته باشیم.
در مثال زیر هنگام دسترسی به ویژگی ۳ با یک خطای سینتکس مواجه خواهیم شد:
let numbers = { one: David, two: George, ۳: Peter } console.log(numbers.two); console.log(numbers.3);
همچنین باید به این موضوع توجه داشته باشیم که همیشه باید یک کاما در انتهای هر مقدار در یک آبجکت، به جز آخرین مقدار موجود قرار دهیم.
آرایهها انواع خاصی از آبجکتها هستند که دادهها را به صورت مرتب ذخیره میکنند. متدهای آرایه، توابع built-in هستند که میتوانند روی یک آرایه فراخوانی شوند تا کاری را روی آن آرایه و یا همراه با آن انجام دهند.
متدهای آرایهای زیادی وجود دارد، اما مواردی که بیشتر از همه در React استفاده خواهیم کرد، متدهای map()
، filter()
و reduce()
هستند.
این متد روی المنتهای آرایه تکرار میشود و یک تابع را روی هر المنت آرایه فراخوانی میکند. در نهایت یک آرایه جدید را برمیگرداند که حاوی نتیجه فراخوانی هر تابع میباشد.
let fruits = ["pawpaw", "orange", "banana"]; let mappedFruits = fruits.map(item => item + "s"); console.log(mappedFruits); // ["pawpaws", "oranges", "bananas"]
این متد ()filter تمام آیتمهای یک آرایه که با یک شرایط خاص مطابقت دارند را برمیگرداند.
let fruits = ["pawpaw", "orange", "banana", "grape"]; let filteredFruits = fruits.filter(fruit => fruit.length > 5); console.log(filteredFruits); // ["pawpaw", "orange", "banana"]
این متد روی تمام المنتهای یک آرایه تکرار میشود و در هر تکرار یک action انجام میدهد. سپس نتیجه آن action به تکرار بعدی منتقل میشود و به این ترتیب ادامه پیدا میکند تا این که نتیجه نهایی را برگرداند.
این متد دو آرگومان نیاز دارد که عبارتند از:
let evenNumbers = [2, 4, 6, 8, 10]; evenNumbers.reduce((sum, current) => sum += current, 0);
تابع یک بلاک کد است که یک وظیفه خاصی را انجام میدهد. تابع یک آرگومان میگیرد، کاری را با استفاده از آرگومان انجام میدهد و در نهایت یک نتیجه را برمیگرداند.
درک مفهوم تابع برای یادگیری React بسیار مهم است زیرا میتوانیم از توابع برای ایجاد کامپوننتهای functional در React استفاده کنیم.
برای تعریف یک تابع از کلمه کلیدی function
و نام تابع همانند زیر استفاده میکنیم:
function plusFour(a) { return a + 4; }
تابع موجود در کد بالا plusFour
نام دارد که آرگومان “a” را میگیرد، با عدد ۴ جمع میکند و نتیجه را برمیگرداند.
برای اجرای یک تابع، آن را با نوشتن نام تابع همراه با ()
فراخوانی میکنیم:
// We will call the plusFour function in the earlier example plusFour();
Arrow functionها روشی جایگزین برای نوشتن توابع هستند. میتوانید تابع plusFour
بالا را به صورت یک Arrow function مانند زیر بازنویسی کنیم:
let plusFour = (a) => { return a + 4; }
از آنجایی که تابع ما فقط یک دستور return در یک خط دارد، میتوانیم Arrow function را به صورت زیر نیز بنویسیم:
let plusFour = (a) => return a + 4;
نکتهای که باید به آن توجه کنیم این است که ما نمیتوانیم از Arrow function به عنوان متد، generator و یا constructor استفاده کنیم. بلکه آنها میتوانند به عنوان تواع معمولی مورد استفاده قرار بگیرد.
قبل از سال ۲۰۱۵ متغیرها، آرایهها، آبجکتها و توابع جاوااسکریپتی ایجاد شده در یک فایل فقط در داخل آن فایل قابل دسترسی بودند. اما با معرفی ES6 در سال ۲۰۱۵، ماژولها نیز به وجود آمدند. ماژولها به ما این امکان را میدهند که آبجکتها، آرایهها، توابع و غیره را در یک فایل تعریف کنیم و از آنها در فایل دیگری استفاده کنیم.
این موضع به ما کمک میکند تا در حالی که برنامه همچنان در حال بزرگتر شدن است اندازه فایل کنترل شده باشد.
ماژولها چیزی هستند که باعث میشوند React به عنوان یک فریمورک SPA (single page application) کار کند. تمام فایلهای دیگر به صورت کامپوننت هستند و در زمان و مکان مورد نیاز import میشوند.
هنگام کار با ماژولها از دو کلمه کلیدی استفاده میکنیم:
export به ما این امکان را میدهد تا محتوای ماژول را در دسترس همه فایلهای جاوااسکریپت دیگر قرار دهیم، در حالی که کلمه کلیدی import کمک میکند تا محتوای موجود را از یک فایل جاوااسکریپتی دیگر به فایل کنونی وارد کنیم.
در مثال زیر تابع cook از فایل آن export شده است.
// file name: cook.js function cook(ingredients, water, heat) { let food = ingredients + water + heat; return food; } export default cook;
سپس در مثال زیر تابع cook به فایل kitchen.js که داریم import شده و فراخوانی میشود.
// file name: kitchen.js import cook from './cook'; cook();
این هفت مفهوم جاوااسکریپت مهمترین مواردی هستند که قبل از یادگیری React باید با آنها آشنا باشیم. با یادگیری این مفاهیم یادگیری React آسانتر خواهد بود زیرا برنامههای آنها را در کد React خود مشاهده خواهیم کرد.