Variable Shadowing (ভেরিয়েবল শ্যাডোয়িং) বিস্তারিত বাংলায়

Variable Shadowing হলো একটি স্কোপিং ঘটনা, যেখানে ইনার স্কোপে ডিক্লেয়ার করা ভেরিয়েবল আউটার স্কোপের একই নামের ভেরিয়েবলকে আড়াল (শ্যাডো) করে ফেলে। ফলে ইনার স্কোপে আউটার ভেরিয়েবল অ্যাক্সেস করা যায় না।


কিভাবে ঘটে?

যখন একই নামের ভেরিয়েবল:

  1. আউটার স্কোপে (যেমন গ্লোবাল স্কোপ বা ফাংশন স্কোপ) ডিক্লেয়ার করা হয়।
  2. ইনার স্কোপে (যেমন ফাংশনের ভেতর বা ব্লক স্কোপ {}) আবার ডিক্লেয়ার করা হয়।

ইনার ভেরিয়েবলটি আউটার ভেরিয়েবলকে “শ্যাডো” করে ফেলে।


উদাহরণ ১: ফাংশন স্কোপে শ্যাডোয়িং

let name = "Global"; // আউটার স্কোপ

function showName() {
  let name = "Local"; // ইনার স্কোপ (শ্যাডো করছে)
  console.log(name); // "Local" (আউটার ভেরিয়েবল আড়াল)
}

showName();
console.log(name); // "Global" (আউটার ভেরিয়েবল অপরিবর্তিত)

ব্যাখ্যা:

  • showName() ফাংশনের ভেতর name ভেরিয়েবলটি গ্লোবাল name-কে শ্যাডো করেছে
  • ফাংশনের ভেতর শুধু লোকাল name-ই অ্যাক্সেসযোগ্য।

উদাহরণ ২: ব্লক স্কোপে শ্যাডোয়িং (ES6 let/const)

let age = 25;

if (true) {
  let age = 30; // ব্লক স্কোপে শ্যাডো করছে
  console.log(age); // 30
}

console.log(age); // 25 (আউটার ভেরিয়েবল অপরিবর্তিত)

ব্যাখ্যা:

  • if ব্লকের ভেতর age ভেরিয়েবলটি বাইরের age-কে শ্যাডো করেছে
  • ব্লক শেষ হলে শ্যাডো উঠে যায়, বাইরের ভেরিয়েবল আবার অ্যাক্সেসযোগ্য হয়।

উদাহরণ ৩: ভেরিয়েবল শ্যাডোয়িং না হলে (প্যারামিটার দিয়ে)

let value = 10;

function updateValue(value) {
  // প্যারামিটার শ্যাডো করছে
  value = 20; // শুধু প্যারামিটার ভেরিয়েবল পরিবর্তন
  console.log(value); // 20
}

updateValue(value);
console.log(value); // 10 (আউটার ভেরিয়েবল অপরিবর্তিত)

ব্যাখ্যা:

  • ফাংশন প্যারামিটার value গ্লোবাল value-কে শ্যাডো করেছে।
  • ফাংশনের ভেতর শুধু প্যারামিটার ভেরিয়েবল পরিবর্তন হয়েছে।

সমস্যা ও সমাধান

সমস্যা ১: আউটার ভেরিয়েবল অ্যাক্সেস করতে না পারা

const data = "Important";

function processData() {
  const data = "Temporary"; // শ্যাডো করছে
  console.log(data); // "Temporary"
  // গ্লোবাল `data` এখানে অ্যাক্সেসযোগ্য নয়!
}

সমাধান: ভিন্ন নাম ব্যবহার করুন বা window অবজেক্ট ব্যবহার করুন (গ্লোবাল ক্ষেত্রে):

function processData() {
  const innerData = "Temporary"; // ভিন্ন নাম
  console.log(window.data); // "Important" (গ্লোবাল অ্যাক্সেস)
}

সমস্যা ২: বাগ তৈরি হওয়া

let count = 0;

function increment() {
  let count = count + 1; // ❌ ReferenceError!
  // কারণ: ইনার `count` ডিক্লেয়ার করার আগেই ব্যবহার করা হচ্ছে
}

সমাধান: শ্যাডো এড়িয়ে আউটার ভেরিয়েবল ব্যবহার করুন:

function increment() {
  count = count + 1; // ✅ শ্যাডো না করে আউটার ভেরিয়েবল আপডেট
}

শ্যাডোয়িং এড়ানোর উপায়

  1. ভিন্ন নাম ব্যবহার করুন:

    let user = "Global";
    function printUser() {
      let currentUser = "Local"; // ভিন্ন নাম
    }
    
  2. আউটার ভেরিয়েবল রিড-অনলি রাখুন:

    const config = { theme: "dark" };
    function setConfig() {
      // config.theme = "light"; // ✅ শ্যাডো না করে মডিফাই
    }
    
  3. গ্লোবাল ভেরিয়েবল এক্সপ্লিসিটলি অ্যাক্সেস করুন:

    let value = 10;
    function show() {
      console.log(window.value); // গ্লোবাল অ্যাক্সেস (ব্রাউজারে)
    }
    

শ্যাডোয়িং কখন উপকারী?

কিছু ক্ষেত্রে ইচ্ছাকৃত শ্যাডোয়িং উপকারী হতে পারে:

  1. ডেটা এনক্যাপসুলেশন: ইনার স্কোপে আউটার ভেরিয়েবল হাইড করে নিরাপদ কোড লেখা।
  2. টেম্পোরারি ভেরিয়েবল: একই নামে টেম্পোরারি ভেরিয়েবল ব্যবহার করে কোড পরিষ্কার রাখা।

উদাহরণ:

function calculateTotal(price, tax) {
  let total = price; // শ্যাডো করে নতুন ক্যালকুলেশন শুরু
  if (tax > 0) {
    total = price + price * tax; // শুধু ইনার স্কোপে পরিবর্তন
  }
  return total;
}

সারসংক্ষেপ

বিষয় ব্যাখ্যা
সংজ্ঞা ইনার স্কোপের ভেরিয়েবল আউটার স্কোপের একই নামের ভেরিয়েবলকে আড়াল করে।
কারণ একই নামে ভেরিয়েবল ডিক্লেয়ার করলে ঘটে।
সমস্যা আউটার ভেরিয়েবল অ্যাক্সেস করা যায় না, বাগ তৈরি হতে পারে।
সমাধান ভিন্ন নাম ব্যবহার, আউটার ভেরিয়েবল এক্সপ্লিসিটলি অ্যাক্সেস।
উপকারিতা ডেটা এনক্যাপসুলেশন, টেম্পোরারি ভেরিয়েবল ম্যানেজমেন্ট।

নোট: শ্যাডোয়িং একটি সাধারণ ঘটনা, কিন্তু অজান্তে শ্যাডো করলে বাগ তৈরি হতে পারে। সচেতনভাবে ভেরিয়েবল নামকরণ করুন! 🚀