การเขียนประกาศนียายหรือวัตถุ ECMAScript
- পূর্ববর্তী পৃষ্ঠা ওবজেক্ট স্কোপ
- পরবর্তী পৃষ্ঠা ওবজেক্ট সংশোধন
প্রিডিফাইন্ড বস্তুর ব্যবহার হল পার্থক্যমূলক ভাবে আপাতকারী ভাষার একটি অংশ, কিন্তু তার সত্যিকারী শক্তি তা নিজস্ব শ্রেণী ও বস্তু তৈরির ক্ষমতায় নিহিত:
ECMAScript বস্তু বা শ্রেণী তৈরির অনেক পদ্ধতি ধারণ করে:
ফ্যাক্টরি পদ্ধতি
মৌলিক পদ্ধতি
কারণ বস্তুর বৈশিষ্ট্যগুলি বস্তু তৈরির পরেও ডাইনামিকভাবে নির্দিষ্ট করা যায়, তাই অনেক ডেভেলপার জেসক্রিপ্টের প্রথম সময়ে নিচের ধরণের কোড লিখতেন:
var oCar = new Object; oCar.color = "blue"; oCar.doors = 4; oCar.mpg = 25; oCar.showColor = function() { alert(this.color); };
উপরোক্ত কোডে, অবজেক্ট car তৈরি করা হয়। তাকে কিছু অ্যাট্রিবিউটস নির্ধারণ করা হয়: তার রঙ নীল, চারটি দরজা, প্রতি গ্যালন জোড়ায় ২৫ মাইল চলতে পারে। শেষ অ্যাট্রিবিউটটি ফাংশনের পুঞ্জীভূত পুঞ্জীভূত একটি সূচক, যার মানে এটি একটি পদ্ধতি। এই কোডটি চালু করার পর, আপনি অবজেক্ট car ব্যবহার করতে পারবেন。
কিন্তু এখানে একটি সমস্যা আছে, তা হল একাধিক car এর ইনস্ট্যান্স তৈরির প্রয়োজন হয়:
সমাধান: ফ্যাক্টরি পদ্ধতি
এই সমস্যা সমাধান করতে, ডেভেলপাররা একটি ফ্যাক্টরি ফাংশন তৈরি করেছেন, যা নির্দিষ্ট ধরণের অবজেক্ট তৈরি এবং ফিরিয়ে দেয়:
যেমন, createCar() ফাংশনটি আগের উল্লেখিত কার অবজেক্ট তৈরির কাজকর্মকে একীভূত করতে ব্যবহার করা যেতে পারে:
function createCar() { var oTempCar = new Object; oTempCar.color = "blue"; oTempCar.doors = 4; oTempCar.mpg = 25; oTempCar.showColor = function() { alert(this.color); }; return oTempCar; } var oCar1 = createCar(); var oCar2 = createCar();
এখানে, প্রথম উদাহরণের সমস্ত কোডগুলো createCar() ফাংশনের মধ্যে রয়েছে। এছাড়াও, একটি অতিরিক্ত কোডও আছে, যা car অবজেক্টকে (oTempCar) ফাংশনের মান হিসাবে ফিরিয়ে দেয়। এই ফাংশনটি ব্যবহার করলে, একটি নতুন অবজেক্ট তৈরি হবে, যা সমস্ত প্রয়োজনীয় অ্যাট্রিবিউটস দেয়া হবে, এবং আগের উল্লেখিত car অবজেক্টকে প্রতিলিপি করবে। এইভাবে, আমরা সহজেই car অবজেক্টের দুটি সংস্করণ (oCar1 এবং oCar2) তৈরি করতে পারি, যারা পূর্ণমাত্রা প্রতিষ্ঠানীকৃত হয়েছে。
ফাংশনে পারামিটার পাঠানো
আমরা createCar() ফাংশনকে সংশোধন করতে পারি, যাতে এটি প্রত্যেকটি অ্যাট্রিবিউটের ডিফল্ট মান পাঠাতে পারে, না সুদূরপ্রসারীভাবে ডিফল্ট মান প্রদান করে:
function createCar(sColor,iDoors,iMpg) { var oTempCar = new Object; oTempCar.color = sColor; oTempCar.doors = iDoors; oTempCar.mpg = iMpg; oTempCar.showColor = function() { alert(this.color); }; return oTempCar; } var oCar1 = createCar("red",4,23); var oCar2 = createCar("blue",3,25); oCar1.showColor(); // আউটপুট "red" oCar2.showColor(); // আউটপুট "blue"
createCar() ফাংশনে পারামিটার যোগ করলে, তৈরি করা হওয়া কার অবজেক্টের color, doors এবং mpg অ্যাট্রিবিউটস নির্ধারণ করতে পারে। এটি দুটি অবজেক্টকে একই অ্যাট্রিবিউটস দেয়, কিন্তু ভিন্ন অ্যাট্রিবিউটস মান দেয়。
ফ্যাক্টরি ফাংশনের বাইরে অবজেক্টের পদ্ধতি নির্ধারণ
যদিও ECMAScript তোমারা দিনের মধ্যে দিনের মধ্যে আরও প্রতিষ্ঠানীকৃত হচ্ছে, কিন্তু অবজেক্ট তৈরির পদ্ধতি অবহেলা করা হয়েছে, এবং এটির প্রতিষ্ঠানীকরণ এখনও প্রতিবাদ করা হচ্ছে। এর কিছুটা কারণ সেম্যান্টিক কারণ (এটি নিজেই new কর্মী ব্যবহার করে ব্যবহার করা হয়েছে না এমন প্রতিষ্ঠানীকৃত দেখায়), অন্যদিকে কার্যকরী কারণ। কার্যকরী কারণটি হল এইভাবে অবজেক্ট তৈরির পদ্ধতি। আগের উদাহরণে, প্রত্যেকবার createCar() ফাংশন ব্যবহার করার সময়, একটি নতুন ফাংশন showColor() তৈরি করা হয়, যার মানে প্রত্যেক অবজেক্টই নিজস্ব showColor() সংস্করণ রাখে। কিন্তু একটি সত্য হল যে, প্রত্যেক অবজেক্টই একই ফাংশনকে ভাগ করে নেয়。
কিছু ডেভেলপার ফ্যাক্টরি ফাংশনের বাইরে অবজেক্টের পদ্ধতি নির্মাণ করে, তারপর তা একটি অপেক্ষাকৃত বৈশিষ্ট্য হিসাবে প্রদর্শন করে, এই সমস্যা থেকে বেরিয়ে আসার জন্য:
function showColor() { alert(this.color); } function createCar(sColor,iDoors,iMpg) { var oTempCar = new Object; oTempCar.color = sColor; oTempCar.doors = iDoors; oTempCar.mpg = iMpg; oTempCar.showColor = showColor; return oTempCar; } var oCar1 = createCar("red",4,23); var oCar2 = createCar("blue",3,25); oCar1.showColor(); // আউটপুট "red" oCar2.showColor(); // আউটপুট "blue"
এইভাবে পুনর্লিখিত কোডে, createCar() ফাংশন পূর্বে showColor() ফাংশন নির্মিত হয়। createCar() ভিতরে, অবজেক্টকে বর্তমানে উপস্থিত showColor() ফাংশনের ইন্দ্রিয়কে দেওয়া হয়। কার্যকরীভাবে, এটা ফাংশন অবজেক্টের পুনর্নির্মাণ প্রকল্পকে সমাধান করে; কিন্তু সেম্যান্টিক্সের দিক থেকে, এই ফাংশন অবজেক্টকে মনে হয় না যে এটা অবজেক্টের পদ্ধতি
সমস্ত এই সমস্যাগুলিডেভেলপার দ্বারাকন্সট্রাক্টরের উপস্থিতি
কন্সট্রাক্টর পদ্ধতি
কন্সট্রাক্টর তৈরি করা ফ্যাক্টরি ফাংশনের মতই সহজ। প্রথম পদক্ষেপ হল শ্রেণীর নাম বাছাই করা, অর্থাৎ কন্সট্রাক্টরের নাম। প্রথমের নাম বড় লিপির দ্বারা শুরু করা হয়, যাতে তা সাধারণত ছোট লিপির নামগুলির থেকে আলাদা থাকে। এই পার্থক্য ছাড়াই, কন্সট্রাক্টর ফ্যাক্টরি ফাংশনের মতই দেখায়। নিচের উদাহরণ দেখুন:
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.showColor = function() { alert(this.color); }; } var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25);
এখানে আপনাকে উপরের কোডটি এবং ফ্যাক্টরির পদ্ধতির পার্থক্যকে ব্যাখ্যা করা হচ্ছে। প্রথমে, কন্সট্রাক্টরের ভিতরে কোনও অবজেক্ট তৈরি করা হয় না, বরং this কীভাবে ব্যবহার করা হয়। new অপারেটরের মাধ্যমে কন্সট্রাক্টর নির্মাণ করার সময়, প্রথম লাইন কোড চালু হওয়ার আগে একটি অবজেক্ট তৈরি করা হয়, এই অবজেক্টকে প্রত্যাহার করতেই this ব্যবহার করা হয়। তারপর এটা সরাসরি this এর বৈশিষ্ট্যকে দেওয়া যায়, ডিফল্ট ভাবে এটা কন্সট্রাক্টরের রিটার্ন হিসাবে ব্যবহৃত হয় (return অপারেটরকে ব্যবহার করতে হয় না)。
এখন, new অপারেটর এবং Car শ্রেণীর মাধ্যমে পরিবর্তনীয় তৈরি করা, ECMAScript-এর সাধারণ পরিবর্তনীয় তৈরির মতোই দেখায়।
আপনি প্রশ্ন করতে পারেন, এইভাবে, ফাংশন পরিচালনায় পূর্ববর্তী পদ্ধতিতে উঠা সমস্যার মতো কোন সমস্যা রয়েছে কি না? হ্যাঁ, আছে。
এমনকি, ফ্যাক্টরি ফাংশনের মতো, কনস্ট্রাকটরটি ফাংশন পুনরাবৃত্তি করে, প্রত্যেক পরিবর্তনীয়কে একটি পৃথক ফাংশন সংস্করণ তৈরি করে। কিন্তু, ফ্যাক্টরি ফাংশনের মতো, বাইরের ফাংশনটি কনস্ট্রাকটরকে পুনরায় লিখা যায়, এবং এইভাবে, এটা সেম্যান্টিক্যালি কোন গুরুত্বপূর্ণ কিছু নয়। এটা হচ্ছে প্রটোটাইপ পদ্ধতির সুবিধা, যা আমরা আগে বলেছি。
প্রটোটাইপ পদ্ধতি
এইভাবে, পরিবর্তনীয়র prototype অপারিটারকে ব্যবহার করে, একটি নতুন পরিবর্তনীয় তৈরি করা হয়。
এখানে, প্রথমে একটি খালি কনস্ট্রাকটর ব্যবহার করে শ্রেণীটির নাম নির্বাচন করা হয়। পরবর্তীতে, সমস্ত বৈশিষ্ট্য ও পদ্ধতি prototype অপারিটারের প্রতিবন্ধকতা দিয়ে নির্বাচন করা হয়। আমরা আগের উদাহরণটি পুনরায় লিখি, কোডটি নিচে দেওয়া হল:
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car();
এই কোডটিতে, প্রথমে কনস্ট্রাকটর (Car) নির্বাচন করা হয়, যাতে কোন কোডই নেই। পরবর্তী কোডগুলি, Car-এর prototype অপারিটারের প্রতিবন্ধকতা দিয়ে কোডটি প্রদান করা হয়, যার মাধ্যমে Car পরিবর্তনীয়র বৈশিষ্ট্য নির্বাচন করা হয়। new Car() কল করার সময়, প্রটোটাইপটির সমস্ত বৈশিষ্ট্যগুলি তৎক্ষণাৎ তৈরি হওয়া বস্তুকে দেওয়া হয়, যার মানে, সমস্ত Car ইনস্ট্যান্সগুলি শুধুমাত্র showColor() ফাংশনের পুঞ্জী সংযোগ পায়। মানসিকভাবে, সমস্ত বৈশিষ্ট্যগুলি একটি বস্তুর অংশ হয়, যার ফলে, আগের দুইটি পদ্ধতিতে উঠা সমস্যা সমাধান করেছে।
এছাড়া, এইভাবে, instanceof অপারেটরটি ব্যবহার করে, দেওয়া পরিবর্তনীয়র পরিবর্তনীয় প্রকার পরীক্ষা করা যায়। তাই, নিচের কোডটি TRUE আউটপুট করবে:
alert(oCar1 instanceof Car); // আউটপুট "true"
প্রটোটাইপ পদ্ধতির সমস্যা
প্রটোটাইপ পদ্ধতিটি একটি ভালো সমাধান দেখায়। দুঃখের কথা যে, এটা তার আশা করা মতোই নয়。
প্রথমে, এই কনস্ট্রাকটরটি কোন প্যারামিটার নেয় না। প্রটোটাইপ পদ্ধতিতে, কনস্ট্রাকটরকে প্যারামিটার পাঠায় অপরিবর্তনীয় একটি বৈশিষ্ট্যের মান প্রদান করা যায় না, কারণ Car1 এবং Car2-এর color বৈশিষ্ট্যটি "blue" এবং doors বৈশিষ্ট্যটি 4, mpg বৈশিষ্ট্যটি 25 হয়। এই মানে, একটি বস্তু তৈরির পরেই বৈশিষ্ট্যের ডিফল্ট মান পরিবর্তন করা যেতে পারে, এটা খুবই অসন্তুষ্টকর, কিন্তু এটা শুধুমাত্র নয়। সত্যিকারের সমস্যা, একটি অপরিবর্তনীয় বৈশিষ্ট্যকে ফাংশনের পরিবর্তে অপরিবর্তনীয় অপরিবর্তনীয় বৈশিষ্ট্যের দিকে ইনপুট করার সময় হয়। ফাংশন সহজেই সমস্যা না হয়, কিন্তু অপরিবর্তনীয় বৈশিষ্ট্যকে বেশিরভাগ সময় একাধিক ইনস্ট্যান্সের মধ্যে ভাগ করা হয় না। পরদিন নিচের উদাহরণটি চিন্তা করুন:
function Car() { } Car.prototype.color = "blue"; Car.prototype.doors = 4; Car.prototype.mpg = 25; Car.prototype.drivers = new Array("Mike","John"); Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car(); var oCar2 = new Car(); oCar1.drivers.push("Bill"); alert(oCar1.drivers); // প্রদর্শন "Mike,John,Bill" alert(oCar2.drivers); // প্রদর্শন "Mike,John,Bill"
উপরোক্ত কোডে, অ্যাট্রিবিউট drivers একটি Array অবজেক্টের পুইন্টার, যাতে "Mike" এবং "John" নাম দুটি রয়েছে। কারণ drivers একটি রেফারেন্স মান, Car-এর দুটি ইনস্ট্যান্সগুলি একই অ্যারেকে সুইক্ষণ করে। তাই, oCar1.drivers-এ "Bill" মান যোগ করলে, oCar2.drivers-এও এই মান দেখা যাবে। এই দুটি পুইন্টারের কোনও একটি প্রদর্শন করলে, "Mike,John,Bill" শব্দসাংহারী দেখা যাবে。
অবজেক্ট তৈরির সময় এত বিভিন্ন সমস্যা হওয়ায়, আপনি হয়তো ভাবছেন যে, কি কোনও সঠিক অবজেক্ট তৈরির পদ্ধতি আছে? উত্তর হল, আছে, কনস্ট্রাক্টর এবং প্রটোটাইপ পদ্ধতিকে মিলিয়ে ব্যবহার করতে হবে。
মিশ্র কনস্ট্রাক্টর/প্রটোটাইপ পদ্ধতি
কনস্ট্রাক্টর এবং প্রটোটাইপ ব্যবহার করে, অন্য প্রোগ্রামিং ভাষার মতো অবজেক্ট তৈরি করা যায়। এই ধারণা খুবই সহজ, অবজেক্টের সব ফাংশনমূলক না অ্যাট্রিবিউটগুলি কনস্ট্রাক্টরের মাধ্যমে নির্ধারিত করা, এবং ফাংশনমূলক অ্যাট্রিবিউটগুলি (পদ্ধতি) প্রটোটাইপের মাধ্যমে নির্ধারিত করা। ফলস্বরূপ, সব ফাংশনগুলি কেবল একবার তৈরি হয়, এবং প্রত্যেক অবজেক্টই নিজস্ব অবজেক্ট অ্যাট্রিবিউট ইনস্ট্যান্সগুলি ধারণ করে。
আমরা আগের উদাহরণটি পুনরায় লিখেছি, কোডটি নিম্নরূপ:
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); } Car.prototype.showColor = function() { alert(this.color); }; var oCar1 = new Car("red",4,23); var oCar2 = new Car("blue",3,25); oCar1.drivers.push("Bill"); alert(oCar1.drivers); // প্রদর্শন "Mike,John,Bill" alert(oCar2.drivers); // প্রদর্শন "Mike,John"
এখন এটা সাধারণ অবজেক্ট তৈরির মতো। সব ফাংশনমূলক না অ্যাট্রিবিউটগুলি কনস্ট্রাক্টরে তৈরি হয়, যার মানে কনস্ট্রাক্টরের প্যারামিটারের মাধ্যমে অ্যাট্রিবিউটের ডিফল্ট মান প্রদান করা যায়। কারণ শুধুমাত্র showColor() ফাংশনের একটি ইনস্ট্যান্স তৈরি হয়, তাই মেমরির ব্যয় হয় না। এছাড়া, oCar1-এর drivers অ্যারেকে "Bill" মান যোগ করলে, oCar2-র অ্যারেকে কোনও প্রভাব ফেলে না, তাই এই অ্যারেগুলির মান প্রদর্শন করলে, oCar1.drivers এর মান "Mike,John,Bill" হবে, oCar2.drivers-এর মান "Mike,John" হবে। প্রকৃতপক্ষে, প্রটোটাইপ ব্যবহার করে, instanceof অপারেটরের মাধ্যমে অবজেক্টের ধরন নির্ণয় করা যায়。
এই পদ্ধতি হলো ECMAScript-এর প্রধান পদ্ধতি, যা অন্যান্য পদ্ধতির বৈশিষ্ট্যগুলোকে ধারণ করে, কিন্তু তাদের প্রভাবশালী প্রভাবকে নয়।কিন্তু, কিছু উন্নয়নকারী এই পদ্ধতিকে সম্পূর্ণরূপেই পরিকল্পিত না বলে মনে করে।
ডাইনামিক প্রটটটাইপ পদ্ধতি
অন্য ভাষায় কাজ করতে সামান্য আদ্যত্ন রাখা করা উন্নয়নকারীদের জন্য, মিশ্রিত কনস্ট্রাক্টর/প্রটটটাইপ পদ্ধতির ব্যবহার একটি সুবিধা নয়।পরম্পরাগতভাবে, ক্লাস নির্দিষ্ট করার সময়, অধিকাংশ পার্শ্বস্থ ভাষাগুলোতে এটিকা ও মেথডকে দৃশ্যমানভাবে নির্দিষ্ট করা হয়。
class Car { public String color = "blue"; public int doors = 4; public int mpg = 25; public Car(String color, int doors, int mpg) { this.color = color; this.doors = doors; this.mpg = mpg; } public void showColor() { System.out.println(color); } }
Java কার ক্লাসের সব এটিকা ও মেথডকে ভালোভাবে প্যাক করে, তাই এই কোডটি দেখার পর জানা যায় যে কী কাজ করবে, এটি একটি বস্তুর তথ্য নির্দিষ্ট করে।কনস্ট্রাক্টর/প্রটটটাইপ পদ্ধতির প্রতিক্রিয়াসম্পর্কে ক্রিটিক করা লোকগুলো বলে, একটি কনস্ট্রাক্টরের মধ্যে এটিকা অনুসন্ধান এবং তার বাইরে মেথড অনুসন্ধান বোঝাপড়ায় অসহজ।তাই, তারা ডাইনামিক প্রটটটাইপ পদ্ধতি ডিজাইন করে, যাতে একটি বেশি সুবিধাজনক কোডিং স্টাইল প্রদান করা যায়。
ডাইনামিক প্রটটটাইপ পদ্ধতির মূল ধারণা কনস্ট্রাক্টর/প্রটটটাইপ পদ্ধতির সঙ্গে একই, অর্থাৎ কনস্ট্রাক্টরের মধ্যে ফাংশন বাহ্যক এটিকে নির্দিষ্ট করা, ফাংশন এটিকে প্রটটটাইপ এটিকে নির্দিষ্ট করা।একমাত্র পার্থক্য হল এই মেথডগুলোকে কোন বস্তুতে দেওয়ার স্থান。
function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); if (typeof Car._initialized == "undefined") { Car.prototype.showColor = function() { alert(this.color); }; Car._initialized = true; } }
Car._initialized = true; পর্যন্ত এই কনস্ট্রাক্টরটি কোনো পরিবর্তন হয়নি।এই সূত্রটি ডাইনামিক প্রটোটাইপ পদ্ধতিতে সবচেয়ে গুরুত্বপূর্ণ অংশ।যদি এই মানটি অপরিভাষিত থাকে, তবে কনস্ট্রাক্টরটি প্রটোটাইপ পদ্ধতিতে অবজেক্টের পদ্ধতি অবধি অবধি নির্ধারণ করবে, এবং Car._initialized কে সত্য হয়ে রাখবে।যদি এই মানটি পরিভাষিত থাকে (যদি এটার মান true হয়, তবে typeof-এর মান Boolean হবে), তবে এই পদ্ধতিটি তৈরি করা হবে না।সংক্ষেপে, এই পদ্ধতিটি ফ্ল্যাগ ( _initialized ) ব্যবহার করে প্রটোটাইপকে কোনো পদ্ধতি দেওয়ার কোনো কার্য করেনা বলে চিহ্নিত করে।এই পদ্ধতিটি একবার তৈরি এবং মান দেওয়া হয়, যা ক্লাসিক OOP ডেভেলপারদের জন্য খুবই সন্তোষজনক
হাইব্রিড ফ্যাক্টরি পদ্ধতি
এই পদ্ধতিটি সাধারণত, পূর্ববর্তী পদ্ধতিকে প্রয়োগ করা যায় না এমন ক্ষেত্রে একটি প্রতিকারণ পদ্ধতি হিসাবে ব্যবহৃত হয়।এর উদ্দেশ্য হল মিথ্যা কনস্ট্রাক্টর তৈরি করা, যা একটি অন্য অবজেক্টের নতুন ইনস্ট্যান্স ফিরিয়ে দেয়
এই কোডটি ফ্যাক্টরি ফাংশনের মতো দেখাচ্ছে:
function Car() { var oTempCar = new Object; oTempCar.color = "blue"; oTempCar.doors = 4; oTempCar.mpg = 25; oTempCar.showColor = function() { alert(this.color); }; return oTempCar; }
ক্লাসিক পদ্ধতির সমতুল্য, এই পদ্ধতিটি new অপারেটর ব্যবহার করে, তারফরা এটা প্রকৃত কনস্ট্রাক্টরের মতো দেখাচ্ছে:
var car = new Car();
Car() কনস্ট্রাক্টরের মধ্যে new অপারেটর ব্যবহার করার কারণে, কনস্ট্রাক্টরের বাইরে অবস্থিত দ্বিতীয় new অপারেটরটি অবহেলা করা হবে, কনস্ট্রাক্টরের মধ্যে তৈরি হওয়া অবজেক্টটি car বিন্দুত্বে প্রত্যাহার করা হবে
এই পদ্ধতিটি ক্লাসিক পদ্ধতির মতোই অবজেক্ট মথডস পরিচালনায় একই সমস্যা রয়েছে।আপনাকে বেশিরভাগ ক্ষেত্রে এই পদ্ধতিকে ব্যবহার না করার পরামর্শ দেওয়া হয়
কোনো পদ্ধতি ব্যবহার করা হবে
এর আগে বলা হয়েছে, এখনও সবচেয়ে বেশি ব্যবহৃত হয় হাইব্রিড কনস্ট্রাক্টর/প্রটোটাইপ পদ্ধতি।এছাড়া, ডাইনামিক প্রিমিটিভ পদ্ধতিও বেশি প্রচলিত, যা কনস্ট্রাক্টর/প্রটোটাইপ পদ্ধতির সমতুল্য কার্যকারিতা প্রদান করে।এগুলির যে কোনো একটি পদ্ধতিকে ব্যবহার করা যেতে পারে।কিন্তু ক্লাসিক কনস্ট্রাক্টর বা প্রটোটাইপ পদ্ধতিকে একলাই ব্যবহার না করুন, কারণ তার ফলে কোডে সমস্যা উত্থাপিত হতে পারে。
উদাহরণ
বস্তুকে আকর্ষণীয় একটি বিষয় হল তাদের দ্বারা সমস্যা সমাধানের পদ্ধতি।ECMAScript-এর সবচেয়ে সাধারণ একটি সমস্যা হল স্ট্রিং জোড়ানোর কার্যকারিতা।অন্যান্য ভাষার মতো, ECMAScript-এর স্ট্রিং অপরিবর্তনীয় হয়, অর্থাৎ তাদের মান পরিবর্তন করা যায় না।নিচের কোডটি চিন্তানো হয়:
var str = "hello "; str += "world";
এই কোডটি মধ্যেমধ্যে করা পদক্ষেপগুলি হল:
- "hello "-কে স্টোরেজ স্ট্রিং তৈরি করা
- "world"-কে স্টোরেজ স্ট্রিং তৈরি করা
- জোড়া ফলাফল স্টোরেজ স্ট্রিং তৈরি করা
- str-এর বর্তমান সামগ্রীকে ফলাফলে কপি করা
- "world"-কে ফলাফলে কপি করা
- str নিয়ে ফলাফলটি অপদান করা
প্রত্যেকবার স্ট্রিং জোড়ার পর পদক্ষেপ 2 থেকে 6 করা হয়, যার ফলে এই অপারেশনটি অত্যন্ত সংস্থান দূষণকারী হয়। এই প্রক্রিয়াটি কখনও কখনও হাজার বা হাজারের পর করা হলে, তাহলে কার্যকারিতা সমস্যা হতে পারে। এই সমস্যা সমাধান করতে, Array অবজেক্টটির মাধ্যমে স্ট্রিংগুলিকে সংরক্ষণ করে, এবং join() মথুদ্দতা (প্যারামিটার হলো খালি স্ট্রিং) ব্যবহার করে, শেষ স্ট্রিং তৈরি করা। এইভাবের কোডটি নিচেরভাবে ব্যবহার করা যেতে পারে:
var arr = new Array(); arr[0] = "hello "; arr[1] = "world"; var str = arr.join("\" ");
এইভাবে, আইন্ডেক্সে যত স্ট্রিং সমাবেশ করা হয়, তা কোনও সমস্যা হবে না, কারণ যুক্তিং অপারেশন কেবল join() মথুদ্দতা কল করার সময় হয়। এই সময়ের পদক্ষেপগুলি হল:
- ফলাফল স্টোরেজ স্ট্রিং তৈরি করা
- প্রত্যেকটি স্ট্রিংকে ফলাফলের উপযুক্ত স্থানে কপি করা
এই সমাধানটি ভালো হলেও, আরও ভালো সমাধান রয়েছে। প্রশ্নটি হল, এই কোডটি তার উদ্দেশ্যকে সত্যিই প্রকাশ করতে পারে না। এটা সহজতর হওয়ার জন্য StringBuffer ক্লাসটিকের মাধ্যমে এই ফাংশনটি প্যাকেজ করা যেতে পারে:
function StringBuffer () { this._strings_ = new Array(); } StringBuffer.prototype.append = function(str) { this._strings_.push(str); }; StringBuffer.prototype.toString = function() { return this._strings_.join("\" "); };
এই কোডটি প্রথমে দেখতে হবে strings অ্যাট্রিবিউট, যার মূল উদ্দেশ্য হল প্রাইভেট অ্যাট্রিবিউট। এটি কেবল append() এবং toString() মথুদ্দতা দুটি রয়েছে। append() মথুদ্দতার একটি প্যারামিটার রয়েছে, যা সেই প্যারামিটারটিকে স্ট্রিং আইন্ডেক্সে যুক্ত করে, toString() মথুদ্দতা আইন্ডেক্সের join() মথুদ্দতা কল করে, যা শুধুমাত্র সংযুক্ত স্ট্রিং ফিরিয়ে দেয়। StringBuffer অবজেক্টটির মাধ্যমে একটি স্ট্রিং গোষ্ঠী সংযুক্ত করতে, নিচের কোডটি ব্যবহার করা যেতে পারে:
var buffer = new StringBuffer(); buffer.append("hello "); buffer.append("world"); var result = buffer.toString();
StringBuffer ওবজেক্ট এবং প্রথাগত স্ট্রিং কনেকশন পদ্ধতির কার্যকারিতা পরীক্ষা করার জন্য নিচের কোডটি ব্যবহার করা যেতে পারে:
var d1 = new Date(); var str = ""; for (var i=0; i < 10000; i++) { str += "text"; } var d2 = new Date(); document.write("Concatenation with plus: ") + (d2.getTime() - d1.getTime()) + " milliseconds"); var buffer = new StringBuffer(); d1 = new Date(); for (var i=0; i < 10000; i++) { buffer.append("text"); } var result = buffer.toString(); d2 = new Date(); document.write("<br />Concatenation with StringBuffer: ") + (d2.getTime() - d1.getTime()) + " milliseconds");
এই কোডটি স্ট্রিং কনেকশনের দুটি পরীক্ষা করে, একটি হলো সংক্ষেপক টাইপার, আরেকটি হলো StringBuffer ক্লাস।প্রত্যেক কার্যক্রমে 10000টি স্ট্রিং জুড়ানো হয়।তারিখের মান d1 এবং d2 পরিচালনার সময়কে নির্ধারণ করতে ব্যবহৃত হয়।ডেট অবজেক্ট তৈরি করার সময়, যদি কোনও প্রামাণ্য প্রাপ্ত না হয়, তবে অবজেক্টকে বর্তমান তারিখ ও সময় দেওয়া হয়।সংযুক্তিকরণ পরিচালনার সময়কে নির্ধারণ করতে, ডেটের মিলিসেকেন্ড মান (getTime() মথডের ফলাফল) একে অপর থেকে হটানো হয়।এটি জাভাস্ক্রিপ্টের কার্যকারিতা পরীক্ষা করার একটি সাধারণ পদ্ধতি।এই পরীক্ষার ফলাফলটি স্ট্রিংবফার ক্লাস এবং সংক্ষেপক টাইপার ব্যবহারের মধ্যে কীরকম কার্যকারিতা পার্থক্য রয় তা নির্ধারণ করতে সাহায্য করে।
- পূর্ববর্তী পৃষ্ঠা ওবজেক্ট স্কোপ
- পরবর্তী পৃষ্ঠা ওবজেক্ট সংশোধন