در این مطلب قصد داریم که با چند مثال ساده نکاتی را برای بهتر نوشتن شرطها در جاوااسکریپت بررسی کنیم. هنگامی که با جاوااسکریپت کار میکنیم، با چالشهای زیادی مواجه هستیم. در این جا به تعدادی از نکاتی که به کوتاهتر شدن کدها و بهتر نوشتن شرطها در جاوااسکریپت کمک میکند، اشاره خواهیم کرد.
// condition function test(fruit) { if (fruit == 'apple' || fruit == 'strawberry') { console.log('red'); } }
در اولین نگاه مثال بالا خوب به نظر میرسد. اما اگر بخواهیم تعداد میوهها را زیاد کنیم، آیا این راه حل درستی است؟ یعنی به ازای هر میوه باید یک عملگر “یا” به شرط اضافه کنیم. خوب در این جا بهتر است که با استفاده از متد includes() کد را بازنویسی کنیم.
function test(fruit) { // extract conditions to array const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (redFruits.includes(fruit)) { console.log('red'); } }
در این جا شرط را به داخل آرایه redFruits بردیم. با انجام این کار، کد سادهتر خواهد شد. متد includes() تعیین میکند که آرایه حاوی یک عنصر خاص است یا خیر که به ترتیب آن را با true یا false بر میگرداند.
به مثال قبلی دو تا شرط زیر را اضافه کنید:
function test(fruit, quantity) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; // condition 1: fruit must has value if (fruit) { // condition 2: must be red if (redFruits.includes(fruit)) { console.log('red'); // condition 3: must be big quantity if (quantity > 10) { console.log('big quantity'); } } } else { throw new Error('No fruit!'); } } // test results test(null); // error: No fruits test('apple'); // print: red test('apple', 20); // print: red, big quantity
در کد بالا ، با استفاده از عبارت if/else در ۳ لایه ، شرط تو در تو داریم.
function test(fruit, quantity) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; // condition 1: throw error early if (!fruit) throw new Error('No fruit!'); // condition 2: must be red if (redFruits.includes(fruit)) { console.log('red'); // condition 3: must be big quantity if (quantity > 10) { console.log('big quantity'); } } }
با انجام این کار یک لایه غیر ضروری شرط را کاهش میدهیم. این استایل برای کد مناسب است، مخصوصا وقتی عبارت if طولانی داشته باشیم. در غیر این صورت شاید مجبور باشیم برای پیدا کردن else به پایین اسکرول کنیم.
در کد زیر میتوانیم با استفاده از معکوس کردن شرطها و برگشت سریع یک لایه دیگر، if را با استفاده از معکوس کردن شرط ها کاهش دهیم.
function test(fruit, quantity) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (!fruit) throw new Error('No fruit!'); // condition 1: throw error early if (!redFruits.includes(fruit)) return; // condition 2: stop when fruit is not red console.log('red'); // condition 3: must be big quantity if (quantity > 10) { console.log('big quantity'); } }
همان طور که مشاهده کردید، این روش بدون شرط تو در تو، به این دلایل برای ما مفید است: کد کوتاهتر، منطقیتر و واضحتر از روش قبلی میشود.
بنابراین همیشه هدف کمتر کردن شرطهای تو در تو و بازگشت سریع است. اما توجه داشته باشید که استفاده بیش از حد آن شاید باعث سردرگمی شود.
اگر به این موضوع علاقهمند هستید، در این لینک بیشتر درباره این موضوع صحبت شده است.
به احتمال زیاد کد زیر برای شما آشنا به نظر برسد. وقتی با جاوااسکریپت کار میکنید، همیشه نیاز است که مقدار null/undefined چک شود و مقدار پیش فرضی به آن اختصاص دهید.
function test(fruit, quantity) { if (!fruit) return; const q = quantity || 1; // if quantity not provided, default to one console.log(`We have ${q} ${fruit}!`); } //test results test('banana'); // We have 1 banana! test('apple', 2); // We have 2 apple!
میتوانیم متغییر q را با اختصاص دادن پارامترهای پیش فرض تخمین بزنیم.
function test(fruit, quantity = 1) { // if quantity not provided, default to one if (!fruit) return; console.log(`We have ${quantity} ${fruit}!`); } //test results test('banana'); // We have 1 banana! test('apple', 2); // We have 2 apple!
توجه کنید که هر پارامتر میتواند پارامتر تابع پیش فرض خود را داشته باشد. به طور مثال میتوانیم مقدار پیش فرض را به صورت زیر به fruit اختصاص دهیم.
function test(fruit = 'unknown', quantity = 1)
حالا اگر fruit یک آبجکت باشد، چگونه می توانیم پارامتر پیش فرض را تعیین کنیم؟
function test(fruit) { // printing fruit name if value provided if (fruit && fruit.name) { console.log (fruit.name); } else { console.log('unknown'); } } //test results test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple
به مثال بالا نگاه کنید. ما میخواهیم fruit.name را چاپ کنیم. اگر مقدار داشت اسم میوه را چاپ کند و اگر مقدار نداشت، unknown را چاپ کند.
با استفاده از پارامتر تابع پیش فرض و destruct، میتوانیم شرط (fruit && fruit.name) را حذف کنیم.
// destructing - get name property only // assign default empty object {} function test({name} = {}) { console.log (name || 'unknown'); } //test results test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple
دستور destruct در جاوااسکریپت، مقدار آرایهها و آبجکتهای اختصاص داده شده را از هم مجزا میکند.
از آنجایی که ما فقط به خاصیت name از fruit نیاز داریم، میتوانیم با استفاده از پارامتر {name ،{name را به عنوان متغییر در کد به جای fruit.name به کار ببریم.
ما همچنین آبجکت خالی {} را به عنوان مقدار پیش فرض اختصاص میدهیم. اگر این کار را انجام ندهیم خطای Undefined را دریافت میکنیم.
روش دیگر استفاده از تابع get در loadash است. کتابخانه loadash آرایه، رشته و آرگومان را پشتیبانی میکند. مقدار name را از آبجکت fruit میگیرد. اگر مقدار آن تعریف نشده باشد مقدار defaultValue را بر میگرداند.
// Include lodash library, you will get _ function test(fruit) { console.log(__.get(fruit, 'name', 'unknown'); // get property name, if not available, assign default value 'unknown' } //test results test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple
در این جا میخواهیم میوهها را بر اساس رنگ چاپ کنیم.
function test(color) { // use switch case to find fruits in color switch (color) { case 'red': return ['apple', 'strawberry']; case 'yellow': return ['banana', 'pineapple']; case 'purple': return ['grape', 'plum']; default: return []; } } //test results test(null); // [] test('yellow'); // ['banana', 'pineapple']
این کد به نظر می رسد که هیچ ایرادی ندارد. ما می توانیم با استفاده از object literal همان نتیجه را بدست بیاوریم ولی درعوض کد تمیزتری داشته باشیم. همان طور که می دانید object literal یکی از روش های ایجاد آبجکت در جاوا اسکریپت است که مقدار key ، value ها داخل {} قرار می گیرند.
// use object literal to find fruits in color const fruitColor = { red: ['apple', 'strawberry'], yellow: ['banana', 'pineapple'], purple: ['grape', 'plum'] }; function test(color) { return fruitColor[color] || []; }
همچنین میتوان با استفاده از map به همان نتیجه رسید. آبجکت map برای ES6 در دسترس است و key و value آن را میتوانید ذخیره کنید. آبجکت map عناصر خود را مثل حلقه for و بر اساس آرایه [key, value] تکرار میشود.
// use Map to find fruits in color const fruitColor = new Map() .set('red', ['apple', 'strawberry']) .set('yellow', ['banana', 'pineapple']) .set('purple', ['grape', 'plum']); function test(color) { return fruitColor.get(color) || []; }
روش دیگر که نتیجه یکسانی با دو روش قبلی دارد، استفاده از متد array.filter است. این متد شامل آرایه جدیدی است که روی آن شرط مورد نظر آرایه بررسی میشود. یعنی همه عناصر آرایه جدید، شرط مورد نظر را دارند.
const fruits = [ { name: 'apple', color: 'red' }, { name: 'strawberry', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'pineapple', color: 'yellow' }, { name: 'grape', color: 'purple' }, { name: 'plum', color: 'purple' } ]; function test(color) { // use Array filter to find fruits in color return fruits.filter(f => f.color == color); }
برای کاهش کد میتوانید از عملکرد جدید جاوااسکریپت استفاده کنید. در این کد ما میخواهیم بررسی کنیم آیا رنگ تمام میوه ها قرمز است یا نه.
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { let isAllRed = true; // condition: all fruits must be red for (let f of fruits) { if (!isAllRed) break; isAllRed = (f.color == 'red'); } console.log(isAllRed); // false }
کد ما این جا خیلی طولانی است می توانیم با استفاده از متدهای every و some کدهای کوتاهتر و تمیزتری داشته باشیم.
با متد every() می توانیم چک کنیم که آیا همه میوه ها رنگشان قرمز است یا نه ، در این متد باید همه عناصر آرایه ، شرط مورد نظر را داشته باشند تا true برگرداند.
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { // condition: short way, all fruits must be red const isAllRed = fruits.every(f => f.color == 'red'); console.log(isAllRed); // false }
برای تست حداقل میوهای که رنگ قرمز دارد، از متد some() استفاده میکنیم. این متد چک میکند که اگر حداقل یک عنصر در آرایه شرط مورد نظر را داشته باشد، مقدار true را برگرداند. چون این جا عنصر apple با رنگ قرمز داریم پس شرط مورد نظر در آرایه را داریم و مقدار true را بر میگرداند.
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { // condition: if any fruit is red const isAnyRed = fruits.some(f => f.color == 'red'); console.log(isAnyRed); // true }
منبع: scotch.io
۵۰ درصد تخفیف ویژه پاییز فرانت کست تا پایان هفته
کد تخفیف: atm
دیدگاهها: