ترفندهایی برای نوشتن کدهای کوتاه در JavaScript
۲۶ فروردین ۱۴۰۰
همانطور که همهی ما میدانیم کمیت کدها میتواند در عملکرد برنامههای وب تاثیرگذار باشد. کدهای طولانی به زمان بیشتری نیاز دارند تا توسط مرورگر دانلود شوند. البته این اختلاف عملکرد اکثرا در برنامههای بزرگ قابل لمس است و شاید نتوانید در برنامههای کوچک این موضوع را متوجه شوید.
بههرصورت ما تصمیم داریم تا در این مقاله به ترفندهای زبان JavaScript که میتوانند به عادتهای خوب برنامهنویسی شما تبدیل شوند بپردازیم بنابراین در پایان این مقاله میتوانید کدهای هوشمندانهتری را در خطهای کمتری بنویسید.
۱) بررسی مقادیر Null، Undefined و Empty
مطمئنا برای توسعهی یک برنامهی ایمنتر همیشه بررسی میکنیم که مقدار متغیر ما هیچکدام از موارد Null، Undefined و Empty نباشد و بههمین دلیل در اولین ترفند میخواهیم به این موضوع بپردازیم.
احتمالا اولین کدی که برای بررسی مقادیر Null، Undefined و Empty بهذهن شما میرسد بهشکل زیر است:
// Longhand version
if (productName !== undefined || productName !== "" || productName !== null) {
console.log(productName)
}
اما با ترفند زیر میتوانیم از شر کدهای اضافی خلاص شویم و کد تمیزتری داشته باشیم:
// Shorthand version
if (productName) {
console.log(productName)
}
۲) شروط چندگانه
اغلب ممکن است از شروط چندگانهای مانند مثال زیر استفاده کنیم:
//longhand
if (x === 'orange' || x === 'red' || x === 'gray') {
// do something
}
اما با استفاده از includes
دیگر نیازی به نوشتن همهی شروط نیست و میتوانیم مقادیری که میخواهیم بررسی شوند را بهشکل زیر در یک آرایه قرار دهیم:
//shorthand
if (['orange', 'red', 'gray'].includes(x)) {
// do something
}
۳) حلقهها
حلقهها نیز از مواردی هستند که قطعا در همهی برنامهها از آنها استفاده میکنیم و در این بخش میخواهیم به این موضوع بپردازیم که چگونه حلقههای خود را هوشمندانهتر بنویسیم:
//longhand
for (var i = 0; i < productsList.length; i++) {
// do things
}
//shorthand (to access the index)
for (let i in productsList) {
// do things
}
// or (to access productsList's elements)
for (let i of productsList) {
// do things
}
// or with foreach
productsList.forEach(element => {
// do things
});
۴) Implicit returns
implicit returns به این شکل است که فانکشن شما بدون استفاده از کلمهی کلیدی return
یک مقدار را برمیگرداند. حال برای تبدیل یک فانکشن عادی مانند مثال زیر:
//longhand
function getProductPrice() {
return quantity * productPrice;
}
میتوانیم از Arrow Function استفاده کنیم که به ما اجازه میدهد بدون استفاده از کلمهی کلیدی return
، مقدار مورد نظر خود را برگردانیم:
//shorthand
getProductPrice = price => quantity * productPrice;
۵) Spread
زمانی که میخواهیم آرایهها را دستکاری کنیم استفاده از عملگر Spread اهمیت پیدا میکند. برای درک این موضوع به مثال زیر دقت کنید:
const team = ['John', 'Adam', 'Yan'];
//longhand
//- joining
const group = ['Sam', 'Chris', 'Sarah'].concat(team);
//- cloning
const newGroup = team.slice();
در مثال فوق برای اضافه کردن آرایه team
به آرایه group
از concat()
و علاوهبرآن از slice()
برای ایجاد یک clone
از آرایه team
استفاده شده است. حال به مثال زیر دقت کنید تا نحوهی استفاده از ...
یا همان عملگر Spread را متوجه شوید:
const team = ['John', 'Adam', 'Yan'];
//shorthand
//- joining
const group = ['Sam', 'Chris', 'Sarah', ...team];
//- cloning
const newGroup = [...team];
۶) Arrow Function
باتشکر از ES6 میتوانیم فانکشنهای سنتی را بهصورت ساده و با کدنویسی کمتر بنویسیم:
//longhand
function welcomeMessage(name) {
console.log('Welcome ', name);
}
//shorthand
welcomeMessage = name => console.log(name);
۷) Template Literals
بسیاری از توسعهدهندگان هنوز هم از کاراکتر +
برای ادغام یک رشتهی متنی و متغیر موردنظرشان استفاده میکنند اما با بهرهگیری از ES6 میتوانیم این کار را با استفاده از ${}
و `
انجام دهیم.
// longhand
const winnerMsg = 'Congrats to the winner: ' + winnerName + ', you got a ' + gift;
// shorthand
const winnerMsg = `Congrats to the winner: ${winnerName}, you got a ${gift}`;
۸) رشتههای چند خطی
برای اینکه نیازی نباشد در رشتههای متنی خود از \n
، \t
یا موارد اینچنینی استفاده کنید، یک راه حل وجود دارد:
// Longhand
const msg = 'Working in conjunction with humanitarian aid agencies,\n\t'
+ 'we have supported programmes to help alleviate human suffering. \n\t';
//Shorthand
const msg = `Working in conjunction with humanitarian aid agencies,
we have supported programmes to help alleviate human suffering.`;
۹) متد find()
در آرایهها
دیگر نیازی نیست تا از حلقهها برای پیدا کردن یک مقدار خاص در آرایهها استفاده کنید زیرا متد find()
این کار را بهآسانی انجام میدهد و علاوهبرآن دیگر نیازی به نوشتن کدهای اضافی نیست:
const animals = [
{ name: 'octopus', animalClass: 'invertebrates' },
{ name: 'shark', animalClass: 'fish' },
{ name: 'toad', animalClass: 'amphibians' },
{ name: 'snake', animalClass: 'reptiles' }
];
//Longhand
function findReptile(name) {
for (let i = 0; i < animals.length; ++i) {
if (animals[i].animalClass === 'reptiles' && animals[i].name === name) {
return animals[i]
}
}
}
// Shorthand
findReptile = name => (
animals.find(animal => animal.animalClass === 'reptiles' && animal.name === name)
)
۱۰) Nullish Coalescing
در بخش Spread Operator به یکی از جالبترین عملگرها در زبان JavaScript پرداختیم و از این بخش به بعد میخواهیم عملگرهای دیگری را بررسی کنیم که در کوتاه نوشتن کدهای JavaScript به ما کمک میکنند.
سینتکس عملگر Nullish Coalescing به شکل زیر است:
a??b
خروجی کد فوق به این صورت است که اگر متغیر a
تعریف شده باشد، آن را در خروجی دریافت میکنیم اما درصورتی که a
تعریف نشده باشد یا مقدار آن null
و undefined
باشد بنابراین خروجی ما مقدار b
خواهد بود.
بهعبارت دیگر میتوانیم بگوییم که با استفاده از ??
درصورتی که اولین پارامتر تعریف شده باشد و مقدار آن null
یا undefined
نباشد، همان پارامتر اول به ما return
میشود اما درغیر اینصورت پارامتر دوم به ما return
خواهد شد.
برای درک بهتر این موضوع میتوانید به مثالهای زیر دقت کنید:
let a=NULL
console.log(a??50) //50
console.log(a) //NULL
let a=10
let c=30
console.log(a??b??c??d) //10
//gives output, the first defined value
۱۱) Logical Nullish Assignment
عملگر دیگری که به سراغ بررسی آن میرویم، Logical Nullish Assignment است و سینتکسی مشابه با عملگر Nullish Coalescing دارد که عملگر assignment یا همان =
به آن اضافه شده است:
a??=b
همچنین یک معادل برای سینتکس این عملگر وجود دارد:
a??(a=b)
احتمالا با مشاهدهی سینتکس فوق میتوانید به دیدگاه کاملتری از عملکرد این عملگر دست پیدا کنید. اگر مقدار a
با null
یا undefined
برابر نباشد، آنموقع مقدار b
به ما return
میشود و درغیر اینصورت مجددا مقدار b
به ما return
میشود با این تغییر که مقدار b
در متغیر a
ریخته خواهد شد.
برای درک بهتر این موضوع به مثال زیر توجه کنید:
let a=NULL
console.log(a??=50) //50
console.log(a) //50
//compare the output of a from the previous example.
۱۲) Optional Chaining
عملگر Optional Chaining کاربرد بسیار جالبی دارد. مطمئنا همهی شما برای دریافت یک prop
از object
مورد نظرتان به این شکل زیر عمل میکنید:
obj.prop
اما این احتمال وجود دارد که prop
مورد نظر در obj
وجود نداشته باشد. حال با استفاده از این عملگر که سینتکس آن بهشکل زیر است:
obj ?. prop
میتوانیم از رخ دادن خطای TypeError
در برنامه جلوگیری کنیم. عملکرد ?.
به این صورت است که اگر مقدار مورد نظر ما موجود باشد، آن را به ما return
میکند اما اگر مقدار مورد نظر ما در obj
بهصورت undefined
یا null
باشد مقدار undefined
به ما return
میشود.
روش دیگری نیز وجود دارد که ما میتوانیم null
یا undefined
بودن object
را نیز بررسی کنیم و آن هم این است که از عملگر .
استفاده کنیم. مثلا اگر به صورت زیر عمل کنیم:
obj . prop
از null
یا undefined
نبودن obj
قبل از اینکه بخواهیم به prop
مورد نظر دسترسی بگیریم، مطمئن خواهیم شد. برای درک بهتر این موضوعها بهتر است برای مطالعهی مثال زیر وقت بگذارید:
let obj= {
person:{
firstName:"John",
lastName:"Doe"
},
occupation: {
compony:'capscode',
position:'developer'
},
fullName: function(){
console.log("Full Name is: "+ this.person.firstName+" >"+this.person.lastName)
}
}
console.log(obj . person . firstName) //John
console.log(obj . human . award) //TypeError: Cannot read property 'award' of undefined
console.log(obj ?. human . award) //TypeError: Cannot read property 'award' of undefined
console.log(obj . human ?. award) //undefined
delete obj?.firstName; // delete obj.firstName if obj exists
obj . fullName ?. () //logs John Doe
obj ?. fullName() //logs John Doe
obj . fullDetails() // TypeError: obj.fullDetails is not a function
obj ?. fullDetails() // TypeError: obj.fullDetails is not a function
obj.fullDetails ?. () //undefined