ক্

ক্লোজার মধ্যে JavaScript

১টি অনুশীলনী

ক্লোজার সম্পর্কে

ক্লোজার হলো JavaScript-এর একটি প্রোগ্রামিং প্যাটার্ন, যা একটি বাইরের লেক্সিক্যাল স্কোপ থেকে আসা ভ্যারিয়েবল একটি নেস্টেড কোড ব্লকের ভিতরে ব্যবহার করার সুযোগ দেয়। JavaScript ক্লোজারকে স্বচ্ছভাবে সমর্থন করে, আর কী যে এগুলো, তা না জেনেই এগুলো প্রায়ই ব্যবহার করা হয়।

// Top-level declarations are global-scope
const dozen = 12;

// Functions create a new function-scope and block-scope.
// Referencing the outer variable here is a closure.
function nDozen(n) {
  return dozen * n;
}

ক্লোজার নামটি ঐতিহাসিকভাবে λ-ক্যালকুলাস থেকে এসেছে এবং scheme (সূত্র) দ্বারা জনপ্রিয় হয়েছে, যা একটি ফাংশনের খোলা ও বদ্ধ ভ্যারিয়েবল বাইন্ডিংকে বোঝায়।

JavaScript-এ ক্লোজার ব্যবহারের কারণ

  1. ডেটা প্রাইভেসি / ডেটা এনক্যাপসুলেশন

    • অন্য ভাষার মতো নয়, ২০২০ সালে প্রাইভেট ভ্যারিয়েবল নির্দিষ্ট করার কোনো উপায় ছিল না। তাই প্রাইভেট ভ্যারিয়েবল কার্যকরভাবে অনুকরণ করতে ক্লোজার ব্যবহার করা যায় (প্রাইভেট ভ্যারিয়েবল নোটেশন চালু করার একটি প্রস্তাব ছিল, যা আপনি এটি পড়ার সময় হয়তো স্ট্যান্ডার্ড হয়ে যেতে পারে)।
    // Consider this function:
    
    const saveNumber = (number) => {
      // The saved value is unaccessible by the outer lexical scope.
      const value = number;
    
      // We can provide access to the primitive value with a function, but the original will never change
      return () => value;
    };
    
    // Attempting to set the variable outside of its lexical scope results in an error
    value = 42;
    
  2. পার্শিয়াল অ্যাপ্লিকেশন

    • ফাংশন ফাংশন রিটার্ন করতে পারে, আর যখন কোনো রিটার্ন করা ফাংশন তার সৃষ্টিকারী ফাংশনের আর্গুমেন্ট ব্যবহার করে, তখন এটি ক্লোজার দিয়ে পার্শিয়াল অ্যাপ্লিকেশন করার একটি উদাহরণ। একে কখনও কখনও ফাংশনের কারিইং বলা হয়।
    // The arguments are applied one-by-one, using closures to arrive at the final result
    function partialBuildUri(scheme) {
      return function (domain) {
        return function (path) {
          return `${scheme}://${domain}/${path}`;
        };
      };
    }
    
    // A function could apply them all at once.
    function buildUri(scheme, domain, path) {
      return partialBuildUri(scheme)(domain)(path);
    }
    
    // Or apply a few to create a flexible system of functions for reuse.
    function buildHttpsExercismUri(path) {
      return partialBuildUri('https')('exercism.org');
    }
    

ভ্যারিয়েবলের জন্য লেক্সিক্যাল স্কোপ

যেকোনো প্রোগ্রামিং ভাষায় ক্লোজার ভ্যারিয়েবল স্কোপের সাথে ঘনিষ্ঠভাবে সম্পর্কিত। JavaScript-এ ভ্যারিয়েবলের জন্য তিন ধরনের লেক্সিক্যাল স্কোপ রয়েছে:

  1. গ্লোবাল স্কোপ: এগুলো এমন ভ্যারিয়েবল, যেগুলো ফাংশন ও ব্লকের বাইরে ডিক্লেয়ার করা হয়।
  2. ফাংশন স্কোপ: এগুলো var কিওয়ার্ড ব্যবহার করে কোনো ফাংশনের ভিতরে ডিক্লেয়ার করা ভ্যারিয়েবল।
  3. ব্লক স্কোপ: এগুলো let ও const কিওয়ার্ড ব্যবহার করে একটি ব্লকের ({...}) ভিতরে ডিক্লেয়ার করা ভ্যারিয়েবল।

বাস্তবে, কোনো ফাংশন (বা ব্লক) যখন বাইরের স্কোপ থেকে একটি ভ্যারিয়েবল ব্যবহার করে, তখন প্রায়ই একটি ক্লোজার তৈরি হয়। JavaScript-এ এটি স্বচ্ছভাবে সমর্থিত, তাই ক্লোজার প্রায়ই আলাদা করে উল্লেখ না করেই ব্যবহৃত হয়।

ফাংশন স্কোপ

var কিওয়ার্ড একটি ফাংশন-স্কোপড ভ্যারিয়েবল ডিফাইন করে। এর মানে হলো, var দিয়ে ডিফাইন করা ভ্যারিয়েবল যে ফাংশনে সেগুলো ডিফাইন করা হয়েছে, তার যেকোনো জায়গায় এবং যেকোনো নেস্টেড লেক্সিক্যাল স্কোপে (ফাংশন বা ব্লক) পাওয়া যায়।

{
  var five = 5;
}

// This will succeed because 'five' exists in the same scope
var tenTimes = five * 10;

ব্লক স্কোপ

let ও const কিওয়ার্ড ব্লক-স্কোপড ভ্যারিয়েবল ডিফাইন করে। let একটি মিউটেবল ভ্যারিয়েবল ডিফাইন করে, যার মান একাধিকবার সেট করা যায় এবং যাকে ডিফাইন করা যায় কিন্তু ইনিশিয়ালাইজ না করে রাখা যায়। const এমন একটি ভ্যারিয়েবল ডিফাইন করে, যাকে ডিফাইন করার সময়ই ইনিশিয়ালাইজ করতে হয়, আর এরপর তার মান আর পরিবর্তন করা যায় না। const ভ্যারিয়েবলে যদি কোনো প্রিমিটিভ ভ্যালু রাখা হয়, তবে তা মিউটেট করা যায় না। আর const ভ্যারিয়েবলে যদি অ্যারে বা অবজেক্ট-এর মতো কোনো রেফারেন্স ভ্যালু রাখা হয়, তবে রেফারেন্সটি বদলানো যায় না, কিন্তু অ্যারের ভিতরের বিষয়বস্তু মিউটেট করা যায়।

এই ব্লকটি লক্ষ্য করুন:

// 'two' is defined at the top-level, therefore available to the global-scope
const two = 2;

{
  // This succeeds, as 'two' is available from the outer lexical scope
  const oneLess = two - 1;
}

// This throws an error because oneLess is not defined outside of the previous inner lexical scope
console.log(oneLess);

ব্লক তৈরি করতে আমরা ইচ্ছেমতো ব্রেস ({...}) ব্যবহার করতে পারি, তবে এগুলো বেশিরভাগ ক্ষেত্রেই if স্টেটমেন্ট, ফাংশন এবং ক্লাস-কে ঘিরে দেখা যায়।

const PI = 3.14;

// This function uses a closure for the value of PI (π)
function areaOfCircle(radius) {
  return PI * radius * radius;
}
GitHub-এর মাধ্যমে সম্পাদনা করুন লিংকটি নতুন একটি উইন্ডো বা ট্যাবে খুলবে

ক্লোজার শিখুন