জাভাস্ক্রিপ্টে প্রোটোটাইপ আসলে কী জিনিস? প্রোটোটাইপ চেইন ও প্রোটোটাইপ ইনহেরিটেন্স বলতে কী বোঝায়?

asked 01 Sep, 07:35

Asaduzzaman%20Sohel's gravatar image

Asaduzzaman Sohel
21211

edited 01 Sep, 11:23

Mosharraf%20Hosain's gravatar image

Mosharraf Hosain ♦
60618


আমরা যখন কোন অবজেক্ট ক্রিয়েট করি সেটা ফাংশন বা এরে বা অবজেক্ট লিটারাল হোক, সেগুলোর সাথে যে প্রপার্টি এবং মেথড ব্যাবহার করি সেখানে একটা লুকানো প্রপার্টি থাকে প্রোটোটাইপ নামে যেটি মূলত একটি অবজেক্ট এটি জাভাস্ক্রিপ্ট ইঞ্জিন অটোমেটিকালি ক্রিয়েট করে দেয়। ধরি আমাদের একটি অবজেক্ট আছে obj নামে, অবজেক্টের বিভিন্ন প্রপার্টি এবং মেথড থাকে, ধরি আমাদের এই obj-এর একটি প্রপার্টি আছে prop1 নামে, আমরা সেটাতে একসেস করি obj.prop1 নামে। আগেই বলেছি যে আমাদের একটা লুকানো অবজেক্ট থাকে প্রোটোটাইপ নামে। এখন যদি সেখানে একটা প্রপার্টি ক্রিয়েট করি prop2 নামে তবে সেটাতে আমরা একসেস করতে পারবো obj.prop2 নামে, কিন্তু কীভাবে? আমরা যখন obj.prop2 লিখে সেটাতে একসেস করার চেষ্টা করবো তখন প্রথমে সেটা obj-তে খুঁজবে যে prop2 নামে কোন প্রপার্টি আছে কিনা, যদি না থাকে তবে সেটা তখন প্রটোটাইপে গিয়ে দেখেবে এবং সেখান থেকে সেটার ভ্যালু রিটার্ন করবে, দেখতে মনে হবে এই prop2-টা আমাদের অবজেক্টে আছে, কিন্তু আসলে সেটা আমাদের প্রটোটাইপে। আবার এই প্রটোটাইপের ভিতরে ঐ প্রটোটাইপের একটা প্রটোটাইপ থাকতে পারে, ধরি সেটার ভিতরে একটা প্রপার্টি আছে prop3 নামে, এখন আমরা যদি obj.prop3-এর ভ্যালু জানতে চাই তখন সেটা obj-তে গিয়ে খুঁজবে, পাবে না, এরপর obj-এর প্রটোটাইপে যাবে, সেখানে না পেয়ে ঐ প্রটোটাইপের প্রটোটাইপে যাবে, গিয়ে সেখান থেকে prop3-এর ভ্যালু রিটার্ন করবে। এভাবে ঐ প্রটোটাইপেরও আরেকটা প্রটোটাইপ থাকতে পারে, একে প্রটোটাইপ চেইন বলে।

এখন ধরি আমাদের আরেকটা অবজেক্ট আছে obj2 নামে, এখন obj2 কিন্তু obj-এর প্রটোটাইপ একসেস করতে পারবে, আমরা যদি obj2.prop2 লিখি তাইলে obj.prop2 এর ভ্যালুই আসবে। একটা উদাহরণ দেই,

var person = { 
  firstName: 'Jhon',
  lastName: 'Doe',
  getFullName: function() {
    return this.firstName + " " + this.lastName;
  }
}

var jack = {
  firstName: "Jack",
  lastName: "Ryan"
}
/*
 সব অবজেক্ট থেকে অন্য অবজেক্টের রেফারেন্স আছে যাকে আমরা প্রটোটাইপ বলি, নিচের লাইনটি শুধু উদাহরণের জন্য ব্যাবহার করা, এটি কখনো কোডিং এর ক্ষেত্রে ব্যাবহার না করাই ভাল।
*/

jack.__proto__ = person; 
/*
 এখানে জ্যাকের প্রটোটাইপটা পার্সনে সেট করা। নরমালি আমরা jack.prototype = Object.Create(Person.prototype) এরকম ব্যাবহার করি।
*/

//এখন আমরা যদি কোন কিছু জ্যাক থেকে কল করি যেটা জ্যাকে নাই কিন্তু পার্সনে আছে তবে সেটা পার্সন থেকে দেখাবে।

console.log(jack.getFullName());

/*
 আমরা এখন ফুল নেইম হিসাবে পাব জ্যাক রায়ান। কিন্তু দেখ ফুল নেইম কিন্তু জ্যাক অবজেক্টে নাই। গেটফুলনেইমের ভিতর 
 যে this আছে প্রথম দিকে কিন্তু সেটা পার্সনে রেফার করছে, কিন্তু এখন সেটি জ্যাক অবজেক্ট রেফার করছে।
*/

console.log(jack.firstName);

/*
 এক্ষেত্রে দেখ, ফার্স্ট নেইম হিসাবে জ্যাক রিটার্ন করবে, যখন আমরা কোন প্রপার্টি/মেথড কল করি তখন সেটা প্রথম 
 অবজেক্টে না পেলে তখন প্রটোটাইপে যায়, এক্ষেত্রে প্রথম অবজেক্টে পাওয়ার পরই সেখানে থেমে গেছে, অর্থাৎ প্রটোটাইপ 
 চেইন এখানেই শেষ।
*/

খেয়াল করে দেখ উপরে আমরা একটা থেকে অন্যটাতে একসেস করছি, যেটা হচ্ছে প্রটোটাইপ ইনহেরিট্যান্স। এর সাথে আরেকটা জিনিস যোগ করি,

var james = {
  lastName: 'Bond'
}
/*
 এখন এটার প্রটোটাইপ আগের মত পার্সন অবজেক্টা সেট করি, আবারও বলছি, নিচের লাইনের মত এভাবে কখনো কোন 
 কোডে ব্যাবহার করা উচিৎ নয়। এটা শুধু উদাহরণ দেয়ার জন্য। 
*/

james.__proto__ = person;
console.log(james.getFullName());
//দেখ এটার ক্ষেত্রে কিন্তু উত্তর আসবে Jhon Bond কারণ james এর কোন ফার্স্ট নেম নেই।

কিন্তু আমরা প্রটোটাইপ কীভাবে সেট করি, কীভাবে ব্যবহার করি এবং কেন ব্যবহার করি?

ধর তুমি ফাংশন দিয়ে একটা অবজেক্ট তৈরি করবে, ধরলাম সেটা Person এবং কয়েকটা অবজেক্ট বানানোর পর তোমার মনে হল যে কয়েকটা অবজেক্টের ক্ষেত্রে একটা age প্রপার্টি থাকা দরকার বা কয়েকটাতে getAge() মেথড থাকা দরকার। এখন তুমি কী করবে? মূল ফাংশনে গিয়ে সেটা লিখবে, এরপর অবজেক্টগুলোতে গিয়ে লিখবে? এর চেয়ে যদি এমন হয়,

Person.prototype.getAge = function() {
  return this.age;
}

সুতরাং তুমি এখন your_object_name.getAge() কল করে সেটাতে একসেস করতে পারলে।

প্রটোটাইপের সুবিধা কী?

ধরি, আমাদের দুই হাজার অবজেক্ট আছে এবং মাত্র বিশটাতে getAge() মেথড দরকার, যদি আমি দুই হাজারটাতে গেটএজ লিখি তাহলে মেমরি কতটুকু খরচ হবে? এর চেয়ে যদি প্রটোটাইপে ব্যাবহার করি তাহলে দুই হাজার গেটএজ ক্রিয়েট হবে না, যখন ঐ বিশটাতে ব্যাবহার করব তখন শুধু সেই বিশটার জন্য ক্রিয়েট হবে।

আরেকটা জিনিস দেখবে যে, কখনও একটা অ্যারে ক্রিয়েট করার পর সেটাতে কনসল থেকে __proto__. দ্বারা দেখবে যে এটার কী কী প্রপার্টি/মেথড আছে। দেখতে পাবে যে এর প্রপার্টি/মেথড হচ্ছে push, pop এইগুলো। আমরা কিন্তু সবসময় সব অ্যারেতে push, pop ব্যবহার করি না, যখন দরকার তখন করি, তখন এটা সেই অ্যারের প্রটোটাইপ থেকে একসেস করে। একই জিনিস তুমি অবজেক্ট এবং ফাংশন ক্রিয়েট করে সেটার প্রটোটাইপের ভিতর কী আছে চেক করতে পারবে।

permanent link

answered 20 Sep, 09:34

Krypton's gravatar image

Krypton
563

edited 22 Sep, 15:17

Mosharraf%20Hosain's gravatar image

Mosharraf Hosain ♦
60618

Your answer
toggle preview

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • link:[text](http://url.com/ "title")
  • image?![alt text](/path/img.jpg "title")
  • numbered list: 1. Foo 2. Bar
  • to add a line break simply add two spaces to where you would like the new line to be.
  • basic HTML tags are also supported

Question tags:

×31
×16

question asked: 01 Sep, 07:35

question was seen: 223 times

last updated: 22 Sep, 15:17