ترفندهای کاربردی در جاوا اسکریپت

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

در این نوشته فهرستی از 11 نکته این چنین را ارائه می‌کنیم که همگی به خاطر وجود یک جنبه ذکاوت یا مفید بودن جمع‌آوری شده‌اند. این مطلب برای افراد مبتدی بسیار مفید است؛ اما امید می‌رود که حتی توسعه‌دهندگان در سطح متوسط جاوا اسکریپت نیز در این فهرست، نکات جدیدی را مشاهده کنند.

با این که بسیاری از این ترفندها در هر زمینه‌ای مفید هستند؛ اما چند مورد از آن‌ها بیشتر برای نوشتن با حداکثر خلاصه‌سازی مفید هستند تا کدی که برای محیط توزیع نهایی مناسب است، چون در محیط production وضوح و خوانایی کد بسیار مهم‌تر از فشردگی آن است. قضاوت در مورد این خصوصیت‌ها را بر عهده شما می‌گذاریم.

فیلتر کردن مقادیر یکتا (Arrays)

نوع شیء set در ES6 معرفی شده است و می‌توان از آن به همراه عملگر spread (…) برای ایجاد یک آرایه جدید با استفاده صرف از مقادیر یکتا بهره گرفت.

const array = [1, 1, 2, 3, 5, 5, 1]

const uniqueArray = [...new Set(array)];

console.log(uniqueArray); // Result: [1, 2, 3, 5]

تا پیش از ES6 جداسازی مقادیر یکتا نیاز به کد بسیار بیشتر از این داشت.

این ترفند برای آرایه‌هایی که شامل انواع ابتدایی یعنی undefined ،null ،boolean ،string و number هستند مناسب است. اگر آرایه‌ای دارید که شامل اشیا، تابع‌ها یا آرایه‌های دیگر است به رویکرد متفاوتی نیاز دارد.

ارزیابی اتصال کوتاه (CONDITIONALS)

عملگر سه‌تایی روشی سریع برای نوشتن گزاره‌های شرطی ساده (و گاهی اوقات نه چندان ساده) به صورت زیر است:

x > 100 ? 'Above 100' : 'Below 100';

x > 100 ? (x > 200 ? 'Above 200' : 'Between 100-200') : 'Below 100';

اما در پاره‌ای موارد حتی عملگر سه‌تایی نیز بیش از حد ضرورت پیچیده است. به جای آن می‌توان از عملگرهای منطقی and (&&) و or (||) برای ارزیابی عبارت‌های خاص به روشی فشرده‌تر استفاده کرد. این وضعیت غالباً به نام «اتصال کوتاه» یا «ارزیابی اتصال کوتاه» نامیده می‌شود.

ارزیابی اتصال کوتاه چگونه کار می‌کند؟

فرض کنید می‌خواهیم تنها یک یا دو گزینه را بازگشت دهیم. با استفاده از && نخستین مقدار false یا کاذب بازگشت می‌یابد. اگر همه عملوندها به صورت true ارزیابی شوند، آخرین عبارت ارزیابی‌شده بازگشت می‌یابد.

let one = 1, two = 2, three = 3;

console.log(one && two && three); // Result: 3

console.log(0 && null); // Result: 0

استفاده از عملگر || نخستین مقدار true یا صادق را بازگشت می‌دهد. اگر همه عملوندها false ارزیابی شوند، آخرین عبارت ارزیابی‌شده بازگشت می‌یابد.

let one = 1, two = 2, three = 3;

console.log(one || two || three); // Result: 1

console.log(0 || null); // Result: null

مثال اول

تصور کنید می‌خواهیم length یک متغیر را پیدا کنیم؛ اما نوع متغیر را نمی‌دانیم. در این شرایط می‌توان از گزاره if/else برای بررسی این که متغیر foo از نوع قابل قبول باشد استفاده کرد؛ اما این رویکرد بسیار طولانی است. «ارزیابی اتصال کوتاه»، امکان این کار را به صورت زیر فراهم می‌سازد:

return (foo || []).length;

اگر متغیر foo صادق باشد، این عبارت مقدار بازگشتی خواهد داشت، در غیر این صورت length آرایه خالی به صورت 0 بازگشت می‌یابد.

مثال دوم

آیا کنون با مسائلی سر و کار داشته‌اید که بخواهید به مشخصه یک شیء تودرتو دسترسی پیدا کنید؟ ممکن است ندانید که آن شیء یا یکی از مشخصه‌های فرعی آن وجود دارند یا نه و این وضعیت منجر به خطاهای ناگواری می‌شود.

تصور کنید می‌خواهیم به یک مشخصه به نام data درون this.state دسترسی پیدا کنیم؛ اما data تا زمانی که برنامه ما یک درخواست واکشی را با موفقیت بازگشت نداده است، تعریف نشده است.

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

if (this.state.data) {

return this.state.data;

} else {

return 'Fetching Data';

}

اما این وضعیت کاملاً مفصل به نظر می‌رسد. عملگر or یک راه‌حل بسیار فشرده‌تر ارائه می‌کند:

return (this.state.data || 'Fetching Data');

نمی‌توان کد فوق را برای استفاده از && «بازسازی» (refactor) کرد. گزاره زیر:

'Fetching Data' && this.state.data

مقدار this.data.state را چه تعریف شده باشد و یا نباشد، بازگشت می‌دهد. دلیل این امر آن است که ‘Fetching Data’ صادق است و از این رو && زمانی که در ابتدا قرار گیرد همواره از آن رد می‌شود.

پیشنهاد یک ویژگی جدید: زنجیره‌سازی اختیاری

در حال حاضر پیشنهاد شده است که «زنجیره‌سازی اختیاری» (Optional Chaining) در زمان تلاش برای بازگشت یک مشخصه از اعماق ساختارهای شبه درختی مورد استفاده قرار گیرد. در این پیشنهاد علامت سؤال (?) می‌تواند برای استخراج مشخصه تنها در صورتی قابل استفاده است که null نباشد.

برای نمونه، می‌توانیم مثال فوق را طوری به صورت this.state.data?. () بازسازی کنیم که data تنها در صورتی بازگشت یابد که null نباشد.

همچنین اگر دغدغه اصلی ما در مورد این باشد که آیا state تعریف شده یا نه، می‌توانیم this.state?.data را بازگشت دهیم. این پیشنهاد هنوز در مرحله 1 و به عنوان یک ویژگی آزمایشی است. البته شما می‌توانید از طریق Babel و از طریق افزودن babel/plugin-proposal-optional-chaining@ به فایل babelrc. از آن استفاده کنید.

تبدیل به بولی (TYPE CONVERSION)

جاوا اسکریپت علاوه بر مقادیر معمول بولی true و false با همه مقادیر دیگر به صورت «صادق» (truthy) یا «کاذب» (falsy) برخورد می‌کند. همه مقادیر در جاوا اسکریپت به جز 0، “” ،null ،undefined ، NaN و البته false صادق هستند.

می‌توان به سادگی بین مقادیر true و false با استفاده از عملگر منفی (!) سوئیچ کرد. این عملگر نوع متغیر را نیز به Boolean تغییر می‌دهد.

const isTrue = !0;

const isFalse = !1;

const alsoFalse = !!0;

console.log(isTrue); // Result: true

console.log(typeof true); // Result: "boolean"

این نوع از تبدیل نوع در گزاره‌های شرطی بسیار کارآمد است؛ اما شاید تنها هدف از این که بخواهیم false را به صورت 1! تعریف کنیم، این است که می‌خواهیم کدمان تا حد امکان فشرده باشد.

تبدیل به رشته (TYPE CONVERSION)

برای تبدیل سریع یک عدد به رشته، می‌توان از عملگر الحاق + و سپس یک مجموعه تهی از علامت نقل قول “” استفاده کرد.

const val = 1 + "";

console.log(val); // Result: "1"

console.log(typeof val); // Result: "string"

تبدیل به عدد (TYPE CONVERSION)

متضاد حالت قبل زمانی است که بخواهیم یک متغیر رشته را به عدد تبدیل کنیم و در این مورد می‌توانیم از یک عملگر جمع + استفاده کنیم.

let int = "15";

int = +int;

console.log(int); // Result: 15

console.log(typeof int); Result: "number"

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

console.log(+true);// Return: 1

console.log(+false); // Return: 0

ممکن است برخی زمینه‌ها باشند که + به جای عملگر جمع به عنوان عملگر الحاق تفسیر شود. زمانی که این اتفاق می‌افتد (و می‌خواهید یک عدد صحیح و نه اعشاری بازگشت یابد) می‌توانید از دو کاراکتر مد ~~ استفاده کنید.

یک کاراکتر مد که به نام «عملگر NOT بیتی» نیز شناخته می‌شود؛ عملگر معادل n — 1- است. از این رو برای مثال، 15~ معادل 16- است.

استفاده از دو کاراکتر مد ~~ پشت سر هم موجب منفی شدن عملیات می‌شود و از این رو محاسبه زیر صورت می‌گیرد:

— ( — n — 1) — 1 = n + 1 — 1 = n

به بیان دیگر 16-~ برابر با 15 است.

const int = ~~"15"

console.log(int); // Result: 15

console.log(typeof int); Result: "number"

گرچه این عملیات کاربردهای زیادی ندارد؛ اما عملگر NOT بیتی روی مقادیر بولی به صورت‌های زیر نیز قابل استفاده است:

true = -2~
false = -1~

توان سریع (OPERATIONS)

از ES7 به بعد امکان استفاده از عملگر نمایی ** به عنوان یک میانبر برای توان فراهم شده است که روش سریع‌تری برای نوشتن (Math.pow(2, 3 است. این دستور سرراستی محسوب می‌شود؛ اما موجب سردرگمی می‌شود، زیرا اغلب راهنماها برای معرفی این عملگر به‌روزرسانی نشده‌اند!

console.log(2 ** 3); // Result: 8

این عملگر نباید با عملگر ^ اشتباه گرفته شود که به طور معمول برای نمایش نماها استفاده می‌شود؛ چون در جاوا اسکریپت عملگر ^ برای نمایش عملگر XOR بیتی استفاده می‌شود.

تا پیش از ES7 این میانبر تنها برای توان‌های در پایه 2 وجود داشت که با استفاده از عملگر شیفت چپ بیتی >> عمل می‌کرد:

// The following expressions are equivalent:

Math.pow(2, n);

2 << (n - 1);

2**n;

تبدیل سریع Float به Integer

اگر بخواهید یک مقدار Float را به Integer تبدیل کنید، می‌توانید از ()Math.floor() ،Math.ceil یا ()Math.round استفاده کنید. اما روش سریع‌تری نیز برای کاهش یک مقدار اعشاری به صحیح با استفاده از | وجود دارد که عملگر OR بیتی است.

console.log(23.9 | 0);// Result: 23

console.log(-23.9 | 0); // Result: -23

رفتار | بسته به این که با مقادیر مثبت یا منفی سروکار داشته باشد متفاوت خواهد بود، بنابراین بهتر است تنها در صورتی که مطمئن هستید از آن استفاده کنید.

اگر n مثبت باشد، n | 0 موجب گرد شدن مطمئن عدد n می‌شود. اگر n منفی باشد، باز به طرز مؤثری گرد می‌شود. برای این که موضوع روشن‌تر شود، باید گفت که این عملیات هر آن چه را که پس از ممیز اعشاری می‌آید حذف می‌کند و بدین ترتیب عدد اعشاری به یک عدد صحیح تبدیل می‌شود.

همان تأثیر گرد کردن از طریق استفاده از ~~ فوق نیز میسر است و در واقع هر عملگر بیتی می‌تواند یک مقدار اعشاری را به مقدار صحیح تبدیل کند. دلایل عملکرد صحیح این عملیات خاص آن است که زمانی روی یک عدد صحیح اعمال می‌شود، مقدار آن بدون تغییر باقی می‌ماند.

حذف ارقام نهایی

عملگر OR بیتی می‌تواند برای حذف هر تعداد از ارقام از انتهای یک عدد صحیح نیز استفاده شود. این بدان معنی است که لازم نیست از کدی مانند زیر برای تبدیل بین نوع‌ها استفاده کنیم:

let str = "1553";

Number(str.substring(0، str.length - 1));

به جای آن عملگر OR بیتی امکان نوشتن کدی به صورت زیر را به ما می‌دهد:

console.log(1553 / 10 | 0)// Result: 155

console.log(1553 / 100 | 0)// Result: 15

console.log(1553 / 1000 | 0)// Result: 1

اتصال خودکار در کلاس‌ها (CALSSES)

می‌توان از نماد Arrow در ES6 برای متدهای کلاس استفاده کرد و بدین ترتیب binding اعمال می‌شود. این حالت در اغلب موارد موجب صرفه‌جویی چندین خط از کد در سازنده کلاس می‌شود و می‌تواند پایانی بر عبارت‌های تکراری مانند (this.myMethod = this.myMethod.bind(this باشد.

import React, { Component } from React;

export default class App extends Compononent {

constructor(props) {

super(props);

this.state = {};

}

myMethod = () => {

// This method is bound implicitly!

}

render() {

return (

<>

<div>

{this.myMethod()}

</div>

</>

)

}

};

کوتاه کردن یک آرایه (ARRAYS)

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

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

array.length = 4;

console.log(array); // Result: [0, 1, 2, 3]

این یک راه‌حل فشرده است. با این وجود، زمان اجرای متد ()slice می‌تواند از این هم سریع‌تر باشد. اگر سرعت هدف اصلی شما است، می‌توانید از چیزی مانند زیر استفاده کنید:

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

array = array.slice(0, 4);

console.log(array); // Result: [0, 1, 2, 3]

دریافت آخرین آیتم‌ها در یک آرایه (ARRAYS)

متد ()slice آرایه می‌تواند اعداد صحیح منفی نیز بپذیرد و در این حالت مقادیر را به جای ابتدا از انتهای آرایه می‌گیرد.

let array = [0، 1، 2، 3، 4، 5، 6، 7، 8، 9];

console.log(array.slice(-1)); // Result: [9]

console.log(array.slice(-2)); // Result: [8، 9]

console.log(array.slice(-3)); // Result: [7، 8، 9]

قالب‌بندی کد JSON

در نهایت احتمالاً تاکنون از JSON.stringify استفاده کرده‌اید؛ اما آیا متوجه شده‌اید که این متد می‌تواند به ایجاد تورفتگی در JSON نیز کمک کند؟ متد ()stringify دو پارامتر اختیاری می‌گیرد، یکی تابع replacer است که برای فیلتر کردن JSON نمایش یافته استفاده می‌شود و دیگری مقدار space است.

مقدار space یک عدد صحیح می‌گیرد که تعداد فاصله‌ها یا رشته‌ای (مانند ‘t\’ برای درج tab) هست که قرار می‌گیرد و موجب می‌شود که خواندن داده‌های JSON واکشی شده بسیار آسان‌تر شود.

console.log(JSON.stringify({ alpha: 'A', beta: 'B' }, null, '\t'));

// Result:

// '{

// "alpha": A,

// "beta": B

// }'

منبع: فرادرس. http://bit.ly/2Iy0qMM

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