خبر و ترفند روز

خبر و ترفند های روز را اینجا بخوانید!

نحوه عملکرد توابع در جاوا اسکریپت

این ویژگی زبان جاوا اسکریپت می تواند به مرتب کردن کد شما کمک کند و درک جدیدی از نحوه عملکرد توابع به شما بدهد.

توابع Curried می توانند به خوانایی و رساتر کردن کد جاوا اسکریپت شما کمک کنند. تکنیک Currying زمانی ایده آل است که می خواهید منطق پیچیده را به کدهای کوچکتر، مستقل و قابل مدیریت تقسیم کنید.

همه چیز را در مورد توابع Curried در جاوا اسکریپت، نحوه استفاده از تکنیک تابع currying برای ایجاد توابع نیمه کاربردی، و همچنین موارد استفاده واقعی برای توابع Curried و جزئی اعمال شده بیاموزید.

Currying چیست؟

Currying از نام ریاضیدان Haskell B. Curry گرفته شده است و این مفهوم از حساب Lambda گرفته شده است. Currying تابعی را می گیرد که بیش از یک پارامتر را دریافت می کند و آن را به یک سری توابع یوناری (یک پارامتری) تقسیم می کند. به عبارت دیگر، یک تابع Curried فقط یک پارامتر را در یک زمان دریافت می کند.

یک مثال اساسی از کارینگ

در زیر نمونه ای از تابع Curried آورده شده است:

function buildSandwich(ingredient1) {
  return (ingredient2) => {
    return (ingredient3) => {
      return `${ingredient1},${ingredient2},${ingredient3}`
    }
  }
}

تابع buildSandwich() تابع دیگری را برمی گرداند – یک تابع ناشناس که آرگومان ingredient2 را دریافت می کند. سپس، این تابع ناشناس تابع ناشناس دیگری را برمی گرداند که ingredient3 را دریافت می کند. در نهایت، این آخرین تابع، قالب تحت اللفظی، راهی برای قالب‌بندی رشته‌ها در جاوا اسکریپت را برمی‌گرداند.

آنچه شما ایجاد کرده اید یک تابع تودرتو است که در آن هر تابع تابع زیر خود را فراخوانی می کند تا زمانی که به پایان برسیم. اکنون، هنگامی که buildSandwich() را فراخوانی می‌کنید و آن را یک پارامتر واحد ارسال می‌کنید، بخشی از تابع را که هنوز آرگومان‌های آن را ارائه نکرده‌اید برمی‌گرداند:

console.log(buildSandwich("Bacon"))

از خروجی می توانید ببینید که buildSandwich یک تابع را برمی گرداند:

مطلب مرتبط:   درک انتقال و انیمیشن در Svelte

خروجی کنسول مرورگر وب که عملکردی را نشان می دهد که یک تابع را برمی گرداند.

برای تکمیل فراخوانی تابع، باید هر سه آرگومان را وارد کنید:

buildSandwich("Bacon")("Lettuce")("Tomato")

این کد “Bacon” را به تابع اول، “Lettuce” را به تابع دوم و “Tomato” را به آخرین تابع منتقل می کند. به عبارت دیگر، تابع buildSandwich () واقعاً به سه تابع تقسیم می شود که هر تابع تنها یک پارامتر دریافت می کند.

در حالی که برای کاری با استفاده از توابع سنتی کاملاً معتبر است، اما هرچه عمیق‌تر می‌شوید، همه تودرتو می‌توانند بسیار زشت شوند. برای دور زدن این موضوع، می‌توانید از توابع پیکان استفاده کنید و از نحو پاک‌تر آنها استفاده کنید:

const buildMeal = ingred1 => ingred2 => ingred3 =>
`${ingred1}, ${ingred2}. ${ingred3}`;

این نسخه بازسازی شده مختصرتر است، مزیت استفاده از توابع پیکان در مقابل توابع معمولی. می توانید تابع را به همان روشی که با تابع قبلی فراخوانی کردید:

buildMeal("Bacon")("Lettuce")("Tomato")

توابع کاری جزئی اعمال شده

توابع جزئی اعمال شده از کاربردهای معمول کاررینگ هستند. این تکنیک مستلزم ارائه تنها آرگومان های مورد نیاز در یک زمان است (به جای ارائه همه آرگومان ها). هر زمان که یک تابع را با پاس دادن تمام پارامترهای مورد نیاز فراخوانی می کنید، می گویید که آن تابع را “اعمال” کرده اید.

بیایید به یک مثال نگاه کنیم:

const multiply = (x, y) => x * y;

در زیر نسخه کاری شده ضرب است:

const curriedMultiply = x => y => x * y;

تابع ()curriedMultiply آرگومان x را برای تابع اول و y را برای تابع دوم دریافت می کند، سپس هر دو مقدار را ضرب می کند.

برای ایجاد اولین تابع جزئی اعمال شده، curriedMultiple() را با پارامتر اول فراخوانی کنید و تابع برگشتی را به یک متغیر اختصاص دهید:

const timesTen = curriedMultiply(10)

در این مرحله، کد تابع ()curriedMultiply را تا حدی اعمال کرده است. بنابراین، هر زمان که بخواهید TimeTen() را فراخوانی کنید، فقط باید آن را یک عدد ارسال کنید و عدد به طور خودکار در 10 ضرب می شود (که در تابع اعمال شده ذخیره می شود):

console.log(timesTen(8)) // 80

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

مطلب مرتبط:   نحوه باز کردن درخواست کشش در GitHub

به مثالی نگاه کنید که به یک مورد استفاده واقعی توسعه وب نزدیکتر است. در زیر یک تابع updateElemText() دارید که شناسه عنصر را در تماس اول، محتوا را در تماس دوم می گیرد و سپس عنصر را بر اساس شناسه و محتوایی که شما ارائه کرده اید به روز می کند:

const updateElemText = id = content
   => document.querySelector(`#${id}`).textContent = content

// Lock the element's id into the function:
const updateHeaderText = updateElemText('header')

// Update the header text
updateHeaderText("Hello World!")

ترکیب تابع با توابع Curried

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

به عنوان مثال، در یک وب سایت تجارت الکترونیک فرضی، در اینجا سه ​​عملکرد وجود دارد که ممکن است بخواهید یکی پس از دیگری (به ترتیب دقیق) اجرا کنید:

const addCustomer = fn => (...args) => {
  console.log("Saving customer info")
  return fn(...args)
}

const processOrder = fn => (...args) => {
  console.log(`processing order #${args[0]}`)
  return fn(...args);
}

let completeOrder = (...args) => {
  console.log(`Order #${[...args].toString()} completed.`);
}

توجه داشته باشید که این کد از کلمه کلیدی let برای تعریف تابع ()completeOrder استفاده می کند. این به شما امکان می دهد یک مقدار را دوباره به متغیر اختصاص دهید و بخشی از نحوه عملکرد محدوده در جاوا اسکریپت است.

در مرحله بعد، باید توابع را به ترتیب معکوس (از داخل به خارج) فراخوانی کنید زیرا می خواهید ابتدا مشتریان را اضافه کنید:

completeOrder = (processOrder(completeOrder));
completeOrder = (addCustomer(completeOrder));
completeOrder("1000")

این خروجی زیر را به شما می دهد:

مطلب مرتبط:   5 جایگزین Heroku برای میزبانی Full Stack رایگان

اسکرین شات که نتایج ترکیب تابع برگزیده را نشان می دهد.

اگر بخواهید توابع بالا را به روش معمولی بنویسید، کد چیزی شبیه به این خواهد بود:

function addCustomer(...args) {
  return function processOrder(...args) {
    return function completeOrder(...args) {
      // end
    }
  }
}

وقتی تابع addCustomer() را فرا می‌خوانید و آرگومان‌ها را ارسال می‌کنید، از داخل شروع می‌کنید و به سمت بالای تابع می‌روید.

تبدیل یک تابع عادی به یک تابع Curried با یک تابع Curry

اگر قصد دارید زیاد از توابع Curried استفاده کنید، می‌توانید فرآیند را با یک تابع کمکی ساده کنید.

این تابع هر تابع عادی را به یک تابع Curried تبدیل می کند. از بازگشت برای رسیدگی به هر تعداد آرگومان استفاده می کند.

const curry = (fn) => {
  return curried = (...args) => {
    if (fn.length !== args.length) {
      return curried.bind(null, ...args)
    }

    return fn(...args);
  }
}

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

const total = (x, y, z) => x + y + z

برای تبدیل این تابع، تابع curry() را فراخوانی کرده و total را به عنوان آرگومان ارسال کنید:

const curriedTotal = curry(total)

اکنون برای فراخوانی تابع، فقط باید همه آرگومان ها را وارد کنید:

console.log(curriedTotal(10)(20)(30)) // 60

اطلاعات بیشتر درباره توابع در جاوا اسکریپت

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