জাভাস্ক্রিপ্ট this কীওয়ার্ড বোঝা
প্রোগ্রামার হতে চাইলে জাভাস্ক্রিপ্ট শিখা প্রায় বাধ্যতামূলক। এটি নম্র khởiমূহূর্ত থেকে আজ একটি শক্তিশালী ভাষায় পরিণত হয়েছে। এখন এটি ফ্রন্টএন্ড, ব্যাকএন্ড, মোবাইল, গেম, ডেস্কটপ অ্যাপ, এমনকি মেশিন লার্নিং — সব জায়গায় ব্যবহৃত হয়।
মাস্টার बनার আগে ফান্ডামেন্টাল শিখতে হবে। this কীওয়ার্ড সম্ভবত আপনার লার্নিং লিস্টের নম্বর এক।
this আসলে কী?
সरल ভাষায়, this একটি পয়েন্টার, জাভাস্ক্রিপ্ট কোডে কোন অবজেক্ট একটি ফাংশন বা মেথড কল করেছে তা রেফারেন্স করার পদ্ধতি। সহজ কথায়, this হলো ডট (.)-এর বাম পাশে যা থাকে।
this-এর দুটি মূল ব্যবহার রয়েছে। উদাহরণসহ আলোচনা করি।
this দিয়ে অবজেক্ট কনস্ট্রাক্ট করা
function Book(title, author, genre) { this.title = title; this.author = author; this.genre = genre; } const book1 = new Book("Lord Of The Rings", "J.R.R. Tolkien", "Fantasy"); const book2 = new Book("Tools Of Titans", "Tim Ferriss", "Self-help"); console.log(book1); console.log(book2);
আউটপুট:
এখানে একটি কনস্ট্রাক্টর ফাংশন ডিফাইন করা হয়েছে যেটি বই অবজেক্ট তৈরি করে (টাইটেল, অথর, জ্যানর প্যারামিটার নেয়)। কনস্ট্রাক্টর ফাংশন হলো অবজেক্টের "ব্লুপ্রিন্ট"।
new কীওয়ার্ড দিয়ে book1 এবং book2 তৈরি করা হয়েছে। প্রতিটি বই অবজেক্টের নিজস্ব প্রোপার্টি ভ্যালু সেট হয়েছে। this দিয়ে প্রতিটি অবজেক্টের প্রোপার্টি অ্যাসাইন করা হয়েছে।
this দিয়ে প্রোপার্টি অ্যাক্সেস করা
const girl = { name: "Sarah", age: 26, introduce() { console.log( "Hi! " + "I'm " + this.name + " and I'm " + this.age + " years old." ); }, };
আউটপুট:
এখানে girl অবজেক্টে name, age প্রোপার্টি এবং introduce মেথড রয়েছে। মেথডটি this.name এবং this.age দিয়ে প্রোপার্টি অ্যাক্সেস করে।
this এবং স্কোপ (Scope) জাভাস্ক্রিপ্টে
গ্লোবাল স্কোপে (ফাংশন বা অবজেক্টের বাইরে) this গ্লোবাল অবজেক্টকে রেফার করে। ব্রাউজারে window হলো গ্লোবাল অবজেক্ট।
যখন আপনি প্রিমিটিভ ডেটা (স্ট্রিং, নাম্বার, বুলিয়ান...), অবজেক্ট, বা ফাংশন ডিক্লেয়ার করেন, সেগুলো গ্লোবাল (window) অবজেক্টের সাথে আট্যাক হয়। "খোলায়" যা লিখবেন সেটি window. লিখে পড়া যাবে।
উদাহরণ:
function returnThis() { return this; }
returnThis() কল করলে যেহেতু গ্লোবাল স্কোপে আছে, window.returnThis() হিসেবে কাজ করে এবং window অবজেক্ট রিটার্ন করে।
অবজেক্ট ফাংশন বা মেথড
যদি একই ফাংশন একটি অবজেক্টের ভিতরে থাকে (অবজেক্ট মেথড) এবং কল করা হয়, তবে সেটি সেই অবজেক্টটি রিটার্ন করে।
const object = { returnThis() { return this; }, }; object.returnThis();
this-এর গোটাগোটি এবং তার তিনটি সমাধান
যদি একটি ফাংশন সরাসরি কোনো অবজেক্টের সাথে টাইড (tied) না থাকে, তবে ফাংশনের ভিতরের this গ্লোবাল অবজেক্টকে রেফার করে।
const weirdBehaviorObject = { directlyTiedFunction() { return this; }, directlyTiedOuterFunction() { return function indirectNestedFunction() { return this; }; }, };
ব্রাউজারে রান করলে:
এখানে indirectNestedFunction কল করলে window রিটার্ন হয়। এটি জাভাস্ক্রিপ্টের একটি বিচিত্র আচরণ যা অনাকাঙ্ক্ষিত ফলাফল দেয়।
সৌভাগ্যয়, তিনটি সমাধান রয়েছে: ১. ক্লোজার (pre-ES6), ২. অ্যারো ফাংশন, ৩. bind মেথড (call/apply-এর সাথে সম্পর্কিত)।
#১ ক্লোজার দিয়ে this সমাধান
ক্লোজার হলো একটি পারসিস্টেন্ট মেমরি স্টোর — ফাংশন ফিনিশ হলে ভেরিয়েবল গায়েব হয় না। নেস্টেড ফাংশন আউটার ফাংশনের ভেরিয়েবল রেফারেন্স করলে জাভাস্ক্রিপ্ট ইঞ্জিন ক্লোজার তৈরি করে।
const objectWithClosure = { closureFunction() { const self = this; return function enclosedFunction() { return self; }; }, };
closureFunction অবজেক্টের সাথে সরাসরি টাইড, তাই this সেটি রেফার করে। self ভেরিয়েবলে সেটি সংরক্ষণ করা হয়েছে। enclosedFunction-এ this সাধারণত window রেফার করে, কিন্তু ক্লোজার দিয়ে আউটার ফাংশনের this অ্যাক্সেস করা হয়েছে।
#২ অ্যারো ফাংশন দিয়ে this সমাধান
ES6-র সেরা ফিচারগুলোর একটি অ্যারো ফাংশন। এটি সংক্ষিপ্ত সিনট্যাক্স দেয় এবং এক লেভেল আপ স্কোপে this খুঁজে বের করে (যেখানে এটি কন্টেইন করা হয়েছে)।
const arrowFunctionObject = { outerFunc() { return () => this; }, };
অ্যারো ফাংশন আসল অবজেক্ট রিটার্ন করেছে, window নয়। কারণ এটি এক লেভেল আপ outerFunc-এ গিয়ে this খুঁজে পেয়েছে, যা arrowFunctionObject-কে রেফার করে। অ্যারো ফাংশনে বিল্ট-ইন ক্লোজার রয়েছে।
নেস্টেড অ্যারো ফাংশন
জাভাস্ক্রিপ্টে আরেকটি গোটাগোটি: অ্যারো ফাংশন শুধু ১ লেভেল আপ দেখে। নেস্টেড অ্যারো ফাংশন রেগুলার ফাংশনের ভিতরে থাকলে সমস্যা হয়।
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }; }, };
এখানে ইনারমোস্ট অ্যারো ফাংশন window রিটার্ন করে কারণ এর কন্টেইনিং রেগুলার ফাংশন অবজেক্টের সাথে সরাসরি টাইড নয়।
তবে অ্যারো ফাংশন ভিতরে অ্যারো ফাংশন থাকলে সমাধান হয়:
const nestedArrowFunctionObject = { outerFunction() { return () => { return () => this; }; }, };
ইনার অ্যারো আউটার অ্যারোতে দেখে, আউটার অ্যারো রেগুলার ফাংশনে দেখে, রেগুলার ফাংশন অবজেক্টের সাথে টাইড — সুতরাং অবজেক্ট রিটার্ন হয়।
#৩ bind মেথড দিয়ে this সমাধান
bind মেথড স্পষ্টভাবে বলে দেয় this কীকে রেফার করবে। এটি আর্গুমেন্ট হিসেবে অবজেক্ট নেয় এবং ফাংশনের this-এর সাথে বান্ধে দেয়।
const arrowNestedInRegularFunctionObject = { outerFunction() { return function regularFunction() { return () => this; }.bind(arrowNestedInRegularFunctionObject); }, };
bind চেইন করে যা window রিটার্ন করত, সেটিকে ডিজায়ারড অবজেক্টের সাথে বান্ধা হয়েছে।
this কঠিন নয় যদি জাভাস্ক্রিপ্ট বুঝেন
ফiu! গভীরে নেমা হয়েছে। প্রশ্ন হতে পারে, this-এর সাথে এত ঝামেলা কেন?
কারণ: জাভাস্ক্রিপ্টের সব কিছুর মতো this লেক্সিক্যালি স্কোপড নয়, এটি ডাইনামিক্যালি স্কোপড। অর্থাৎ জাভাস্ক্রিপ্ট ইঞ্জিন রানটাইমে (কোড এক্সিকিউশনের সময়) নির্ধারণ করে this কীকে রিপ্রেজেন্ট করবে, কলার কে এবং কোথা থেকে কল হয়েছে তা দেখে।
অন্যদিকে, জাভাস্ক্রিপ্টের বাকি সব কিছু লেক্সিক্যালি স্কোপড — এর ভ্যালু কোড লেখার সময় নির্ধারিত হয়।
this-এর কারণে আমরা একবার অবজেক্ট "ব্লুপ্রিন্ট" বানিয়ে ডাইনামিক্যালি ভিন্ন প্রোপার্টি ভ্যালুয়ালা অবজেক্ট তৈরি করতে পারি (বই উদাহরণ)। this.wanted_property দিয়ে মেথড বানাতে পারি যা অবজেক্টের প্রোপার্টি এক্সপোজ ও ম্যানিপুলেট করে।
জাভাস্ক্রিপ্টের विचित्रতাগুলো নিয়ন্ত্রণ করে আপনি আত্মবিশ্বাসের সাথে কোড লিখতে পারবেন।
এখন আপনি জাভাস্ক্রিপ্টে this বুঝতে পেরেছেন, আরও কিছু ফান্ডামেন্টাল কনসেপ্ট জানতে পেরেছেন — এখন এক্সপেরিমেন্ট, প্র্যাকটিস করুন এবং জাভাস্ক্রিপ্ট মাস্টারি দিকে আত্মবিশ্বাসের সাথে বড়ুন।
আপনার this আপনার হাতে!