জাভাস্ক্রিপ্ট ভাষার সবচেয়ে বড় বুজওয়ার্ডগুলির মধ্যে একটি হল বন্ধ করা৷ এটি FAANG কোম্পানিতে অনেক চাকরির ইন্টারভিউ প্রশ্নের বিষয়। এই নিবন্ধে, আমরা ক্লোজার এবং সুযোগ সম্পর্কে কথা বলব, সহজ উদাহরণ দিয়ে এর ধারণাগুলিকে ব্যাখ্যা করব এবং তারপরে বড় টেক জায়ান্টদের একজনের সাথে একটি সাক্ষাৎকার থেকে একটি নমুনা প্রশ্ন দিয়ে শেষ করব৷
ব্যাপ্তি
যখন কেউ আপনাকে বলে যে একটি প্রকল্পের সুযোগ আছে বা নেই, তার মানে কি?
আমি যখন এর উত্তরের কথা ভাবি তখন আমি একটি পেরিস্কোপ বা টেলিস্কোপের কথা ভাবতে চাই। এই যন্ত্রগুলি আমাদের এটির লেন্সের সীমাবদ্ধতার মধ্যে সব ধরণের জিনিস দেখায়:এটি স্কোপের মধ্যে রয়েছে . যদি এটি স্কোপের বাইরে হয় , আপনি লেন্সের ব্যাস অতীত দেখতে পারবেন না। এবং ব্যাসের বাইরের কিছুতে আলো জ্বালানো সম্ভব নয়। আপনার এই বিষয়ে চিন্তা করা উচিত কারণ আমরা জাভাস্ক্রিপ্টে তিনটি অত্যন্ত গুরুত্বপূর্ণ এবং স্বতন্ত্র ধরনের সুযোগ সম্পর্কে কথা বলি:স্থানীয়, বিশ্বব্যাপী এবং আভিধানিক।
স্থানীয় সুযোগ
আমরা আজ যে তিনটি স্কোপের কথা বলবো তার মধ্যে স্থানীয় স্কোপ হল সবচেয়ে ছোট। যখন আমরা একটি ফাংশন ঘোষণা করি, তখন বন্ধনীর ({}) ভিতরের যেকোনো কিছুকে ফাংশনের স্থানীয় বলে মনে করা হয়। যখন জাভাস্ক্রিপ্ট ইঞ্জিন ফাংশনটি পড়ে তখন এটি ভেরিয়েবল ঘোষণা করবে; এটি শেষ হলে এটি ভেরিয়েবলগুলিকে ধ্বংস করবে।
function greeting() {
var websiteName = 'Career Karma';
return `Hello ${websiteName}`;
}
console.log(greeting()); // Hello Career Karma
console.log(websiteName); // ReferenceError: websiteName is not defined
আপনি দেখতে পাচ্ছেন, যখন আমরা "console.log()" আমন্ত্রণকৃত অভিবাদন ফাংশনের ফলাফল করি, আমরা ফাংশনটি কার্যকর হওয়ার পরে websiteName অ্যাক্সেস করতে সক্ষম হই। এটি আমাদের 'হ্যালো ক্যারিয়ার কর্ম' স্ট্রিং দেয় যা আমরা খুঁজছিলাম। console.log() ফাংশনের ভিতরে ঘোষিত ভেরিয়েবলের একটি ত্রুটি ছুড়ে দেয় কারণ এটি সংজ্ঞায়িত করা হয়নি।
ইতিমধ্যেই উল্লেখ করা হয়েছে, websiteName অনির্ধারিত হওয়ার কারণ হল ভেরিয়েবলগুলি ফাংশনের ভিতরে তৈরি হয় যখন সেগুলিকে আহ্বান করা হয় এবং তারপর যখন টার্মিনাল স্টেটমেন্ট চলে তখন ধ্বংস হয়ে যায়। ফাংশনের বাইরের যেকোন কিছুর একটি বিশেষ সেটআপ না থাকলে ফাংশনের ভিতরের জিনিসগুলিতে অ্যাক্সেস নেই৷
গ্লোবাল স্কোপ
এই পরবর্তী সুযোগটি শব্দগুচ্ছের আক্ষরিক অনুবাদ। একটি গ্লোবাল স্কোপ একটি ফাংশনের বাইরে ঘোষিত আইটেমগুলি নিয়ে যায় এবং সেগুলিকে এমন একটি জায়গায় সংরক্ষণ করে যেখানে সমস্ত স্ক্রিপ্ট এবং পদ্ধতি এবং ফাংশনগুলি তাদের যুক্তির জন্য সেগুলি অ্যাক্সেস করতে এবং ব্যবহার করতে পারে।
let counter = 0; // global -- declared outside function
const add = () => { // function declaration
let counter = 0; // local -- declared inside function
counter += 1;
// counter increased by 1 -- which counter variable increased?
return counter;
}
add(); // invoke
add(); // three
add(); // times
console.log(counter) // is this 3 or 0? Why?
আমরা console.log() হলে উপরের কোডটি কী করে কোড শেষে কাউন্টার? আপনি কি ঘটতে আশা করেন?
81% অংশগ্রহণকারী বলেছেন যে তারা বুটক্যাম্পে যোগ দেওয়ার পরে তাদের প্রযুক্তিগত কাজের সম্ভাবনা সম্পর্কে আরও আত্মবিশ্বাসী বোধ করেছেন। আজই একটি বুটক্যাম্পের সাথে মিলিত হন৷
৷গড় বুটক্যাম্প গ্র্যাড একটি বুটক্যাম্প শুরু করা থেকে শুরু করে তাদের প্রথম চাকরি খোঁজা পর্যন্ত ক্যারিয়ারের পরিবর্তনে ছয় মাসেরও কম সময় ব্যয় করেছে।
আসুন কোডের মাধ্যমে চলুন:
- বৈশ্বিক পরিবেশে কাউন্টার ভেরিয়েবল ঘোষিত এবং শুরু করা হয়েছে।
- গ্লোবাল এনভায়রনমেন্টে ঘোষিত ফাংশন যোগ করুন।
- যোগ করার আহ্বান জানানো হয়েছে।
- স্থানীয় পরিবেশে কাউন্টার ভেরিয়েবল ঘোষিত এবং শুরু করা হয়েছে।
- স্থানীয় কাউন্টার 1 দ্বারা বৃদ্ধি পায় ⇐ কেন স্থানীয় এবং বিশ্বব্যাপী নয়?
- কাউন্টার ফেরত দেওয়া হয়েছে। ফাংশন বন্ধ হয়ে যায়।
- আবার যোগ করা হয়েছে
- আবার 4 থেকে 6 ধাপে হাঁটুন।
- আবার ৩ থেকে ৬ ধাপের পুনরাবৃত্তি করুন।
console.log(counter); ⇐ কি ফেরত দেওয়া হয়?
যেহেতু প্রতিবার কাউন্টারটি 1 এ থাকলে ফাংশনটি বন্ধ হয়ে যায়, আমাদের স্থানীয় কাউন্টার ভেরিয়েবলটি পুনঃঘোষিত হয় এবং প্রতিবার ফাংশন চালানোর সময় 0 এ পুনরায় শুরু হয়। যাই ঘটুক না কেন, কাউন্টারটি সর্বদা স্থানীয় পর্যায়ে 1 এ থামবে।
যদি একটি ফাংশন তার সুযোগের মধ্যে একটি ভেরিয়েবল খুঁজে পায়, তবে এটি ভেরিয়েবলের জন্য বিশ্বব্যাপী সুযোগের দিকে তাকায় না - তাই গ্লোবাল ভেরিয়েবল কখনই পরিবর্তিত হয় না। সুতরাং, আমাদের console.log() 0 আউটপুট হবে যে বিবৃতির পরিবেশের মধ্যে আমাদের নিকটতম সংজ্ঞায়িত পরিবর্তনশীল বৈশ্বিক পরিবেশে রয়েছে।
লেক্সিকাল স্কোপ
আভিধানিক সুযোগ হল জাভাস্ক্রিপ্টের সবচেয়ে মৌলিক ধারণাগুলির মধ্যে একটি। এটি এমন ধারণা যে একটি ফাংশন বা একটি ভেরিয়েবল তৈরি করা কোডের নির্দিষ্ট অংশগুলিতে অ্যাক্সেসযোগ্য হবে এবং তারপর কোডের অন্যান্য অংশগুলিতে অ্যাক্সেসযোগ্য হবে না। এটা সব নির্ভর করে যেখানে প্রতিটি ভেরিয়েবল এবং ফাংশনের ঘোষণা আছে।
আসুন কোডের এই ব্লকটি একবার দেখে নেওয়া যাক:
const init = () => { // <== This is our outer function
const var1 = 'Career'; // outer scope
const second = () => { // <== This is our inner function
const var2 = 'Karma'; // inner scope
console.log(var1); // Career
console.log(var2); // Karma
return var1 + " " + var2;
};
// console.log(var2); // undefined
return second();
};
init();
এখানে আমরা নেস্টেড ফাংশন একটি সেট আছে. init() ফাংশন var1 নামক একটি ভেরিয়েবল ঘোষণা করে, দ্বিতীয় নামক একটি ফাংশন ঘোষণা করে এবং second() আহ্বান করে .
কম্পাইলার যখন প্রথমবার এই কোডের মধ্য দিয়ে যায়, তখন আমাদের কাছে কী আছে তা উচ্চ স্তরের নজরে পড়ে:
init()ফাংশন- আমন্ত্রণ করুন
init()
এই মুহুর্তে, আমরা init() ফাংশনের ভিতরে অন্য কিছু দেখতে পাচ্ছি না - আমরা শুধু জানি ফাংশনটি বিদ্যমান। যখন আমাদের init() func invok করা হয়, তখন কম্পাইলার ফাংশনের ভিতরে কী আছে তা আরও একটি উচ্চ স্তরের নজর দেয়:
var1second()ফাংশন- আমন্ত্রণ করুন
second()
init() ফাংশন second() এর ভিতরে কি ঘটছে সে সম্পর্কে কিছুই জানে না ব্লক এটি শুধুমাত্র তার আভিধানিক পরিবেশে কি আছে তা দেখতে পারে - এর পার্শ্ববর্তী অবস্থা।
প্রতিটি নেস্টেড ফাংশন একটি ছোট পাত্রে থাকে, যেমন রাশিয়ান ম্যাট্রিওশকা নেস্টিং পুতুলের সেট (উদাহরণস্বরূপ পৃষ্ঠার শীর্ষে দেখুন যদি আপনি সেগুলি সম্পর্কে নিশ্চিত না হন)। পুতুলগুলি কেবলমাত্র তাদের পাত্রের ভিতরে কী ঘটছে এবং পিতামাতার মধ্যে ইতিমধ্যে কী ঘটেছে বা ঘোষণা/পড়া হয়েছে সে সম্পর্কে জানে। উদাহরণস্বরূপ সবচেয়ে বড় পুতুলটি কেবল জানে যে তার পাত্রে পরবর্তী পুতুলটি বিদ্যমান। এটি সেটের অন্য কোনও পুতুল সম্পর্কে জানে না, শুধু এর আভিধানিক পরিবেশে (এর অবস্থা) এবং ইতিমধ্যে কী ঘটেছে (বাহ্যিক সুযোগ)।
সারমর্মে, আমরা দুটি জিনিস জানি:
- বাইরের সুযোগ ভিতরের সুযোগ দেখতে পারে না।
- অভ্যন্তরীণ সুযোগের বাইরের সুযোগে অ্যাক্সেস রয়েছে।
যেহেতু বাহ্যিক মোকাবেলা অভ্যন্তরীণ পরিধিতে কী ঘটছে তা দেখতে পাচ্ছে না, আমরা নিরাপদে বলতে পারি যে এটি একটি একমুখী সম্পর্ক। অভ্যন্তরীণ বাইরের সুযোগ থেকে ভেরিয়েবল দেখতে এবং ব্যবহার করতে পারে, কিন্তু বাইরের অভ্যন্তরীণ দেখতে পারে না। একে বলা হয় লেক্সিক্যাল স্কোপ .
আভিধানিক স্কোপিংয়ের সৌন্দর্য হল যে একটি পরিবর্তনশীলের মান কোডে তার বসানো দ্বারা নির্ধারিত হয়। ফাংশনগুলি প্রথমে এটির স্থানীয় পরিবেশের ভিতরে একটি ভেরিয়েবলের অর্থ সন্ধান করে - যদি এটি এটি খুঁজে না পায় তবে এটি সেই ফাংশনে চলে যায় যা সেই ফাংশনটিকে সংজ্ঞায়িত করে। যদি এটি সেখানে এটি খুঁজে না পায় তবে এটি চেইনটিকে পরবর্তী সংজ্ঞায়িত ফাংশনে নিয়ে যায়।
এটি জাভাস্ক্রিপ্টের একটি অত্যন্ত গুরুত্বপূর্ণ ধারণা হয়ে ওঠে যা বারবার উঠে আসবে যখন আপনি জাভাস্ক্রিপ্ট ফ্রেমওয়ার্ক এবং সেগুলি কীভাবে কাজ করে সে সম্পর্কে আরও জানবেন। আপনি বাইরের দিক থেকে নীচে যেতে পারেন, কিন্তু আপনি কখনই অন্য দিকে "উপরে" যেতে পারবেন না। এটি খুবই গুরুত্বপূর্ণ কারণ আমরা প্রধান বিষয়ের কাছে পৌঁছেছি:বন্ধ .
বন্ধ
বন্ধের সংজ্ঞা আভিধানিক সুযোগের সাথে খুব মিল। উভয়ের মধ্যে প্রধান পার্থক্য হল যে বন্ধ করা একটি উচ্চ ক্রম ফাংশন এবং আভিধানিক স্কোপিং নয়। একটি উচ্চ ক্রম ফাংশন একটি মৌলিক বৈশিষ্ট্য আছে:এটি একটি ফাংশন প্রদান করে বা একটি ফাংশন একটি প্যারামিটার হিসাবে ব্যবহার করে।
ক্লোজার এমন একটি ফাংশন যা এর আভিধানিক সুযোগ অ্যাক্সেস করতে পারে, এমনকি যখন সেই ফাংশনটি পরে আহ্বান করা হচ্ছে।
ক্লোজার এবং আভিধানিক সুযোগ উভয়েরই নিজস্ব ভেরিয়েবল রয়েছে, একটি প্যারেন্ট ফাংশনের ভেরিয়েবল এবং প্যারামিটার অ্যাক্সেস করতে পারে এবং গ্লোবাল ভেরিয়েবল ব্যবহার করতে পারে। চলুন নিম্নলিখিত কোড মাধ্যমে হাঁটা:
function greeting() { //outer scope (parent function)
const userName = "CrrKrma1952"; // parent variable
function welcomeGreeting() { // inner function
console.log("Hello, " + userName); // accesses parent var
return "Hello, " + userName; // terminal statement
}
return welcomeGreeting; // returns a function (which makes it HOF)
} // end of greeting()
const greetUser = greeting(); //
greetUser(); // Hello, CrrKrma1952 greeting()ফাংশন বিদ্যমান, কিন্তু আমরা এখনও বিষয়বস্তু জানি না।greetUserবিদ্যমান, কিন্তু বিষয়বস্তু এখনও জানি নাgreetUser()- এটি পূর্ববর্তী লাইনকে আহ্বান করে, যা ঘুরে, greeting() ফাংশনকে আহ্বান করে।- ব্যবহারকারীর নাম ঘোষণা করা হয়েছে
welcomeGreeting()বিদ্যমান, কিন্তু বিষয়বস্তু এখনও জানি না-
welcomeGreeting()এর নিচে রিটার্ন স্টেটমেন্ট ব্লক সেই একই ফাংশন প্রদান করে console.log(‘Hello, ‘ + userName); এখানে আমাদের console.log userName
-এর মান পেতে প্যারেন্ট স্কোপ অ্যাক্সেস করতে পারে - টার্মিনাল স্টেটমেন্ট যা ফাংশন শেষ করে এবং কোড ব্লকের ভিতরে ভেরিয়েবলের অর্থ নষ্ট করে।
এই কোডে, আমরা একসাথে ফাংশন নেস্ট করে তথ্য আদান-প্রদান করছি যাতে প্যারেন্ট স্কোপ পরে অ্যাক্সেস করা যায়।
উপসংহার
এই নিবন্ধে, আমরা একটি চমত্কার ভারী জাভাস্ক্রিপ্ট বিষয় সম্পর্কে কথা বলেছি:সুযোগ এবং বন্ধ। আমি এই বিষয়ে বিভিন্ন প্রবন্ধের শাখা তৈরি এবং পড়ার সুপারিশ করব। এটি যেভাবে শেখানো হয় তা বিভিন্ন দৃষ্টিকোণ থেকে আসতে পারে - যার মানে, অবশ্যই, এটি শেখার অনেক উপায় রয়েছে। আমি আশা করি এই প্রাইমার আপনার জন্য সহায়ক ছিল! বন্ধের উপর আপনার অধ্যয়ন চালিয়ে যাওয়ার জন্য সৌভাগ্য!