ECMAScript অবজেক্ট পরিবর্তন

ECMAScript-এর মাধ্যমে, কেবল অবজেক্ট তৈরি করা নয়, এছাড়াও পুরনো অবজেক্টের আচরণ পরিবর্তন করা যায়。

prototype প্রতিভূতি প্রক্রিয়াটি কেবল কন্সট্রাক্টরের অভিন্নতা এবং পদ্ধতি নির্দিষ্ট করতে পারে, এছাড়াও স্থানীয় অবজেক্টে অভিন্নতা এবং পদ্ধতি যোগ করতে পারে。

নতুন পদ্ধতি নির্মাণ

সম্প্রতির পদ্ধতিগুলির মাধ্যমে নতুন পদ্ধতি নির্মাণ

কোনও শ্রেণীকে prototype অপারেটরের মাধ্যমে নতুন পদ্ধতি নির্মাণ করা যায়, যেমন নিজস্ব শ্রেণীকে পদ্ধতি নির্মাণ করে থাকে। উদাহরণস্বরূপ, Number শ্রেণীর toString() পদ্ধতিকে মনে রাখুন, যখন এটিকে 16 প্রমাণ্য পরামর্শ দেওয়া হয়, তখন এটি ষোড়শানুক্রমিক চিহ্নিত শ্রেণী ফলাফল প্রকাশ করে। যদি এই পদ্ধতির প্রমাণ্য পরামর্শ 2 হয়, তখন এটি দ্বিতীয়াংশানুক্রমিক চিহ্নিত শ্রেণী ফলাফল প্রকাশ করে। আমরা একটি পদ্ধতি তৈরি করতে পারি যা সংখ্যা ওবজেক্টকে সরাসরি ষোড়শানুক্রমিক চিহ্নিত শ্রেণী ফলাফলে রূপান্তরিত করতে পারে। এই পদ্ধতিটি তৈরি করা খুবই সহজ:

Number.prototype.toHexString = function() {
  return this.toString(16);
};

এই পরিবেশে, শব্দকোষ this Number ইনস্ট্যান্সের দিকে নির্দেশ করে, তাই Number ইনস্ট্যান্সের সকল পদ্ধতিকে পূর্ণ ব্যবহার করা যায়। এই কোডটির মাধ্যমে, নিচের কাজটি করা যাবে:

var iNum = 15;
alert(iNum.toHexString());		//ফলে "F" প্রকাশ করা হবে

TIY

কারণ 15 হলো ষোড়শানুক্রমিকতার F, তাই নোটিশ "F" দেখা যাবে。

সম্প্রতির পদ্ধতিগুলির নামকরণ

আমরা সম্প্রতির পদ্ধতিগুলির নামকরণটিকে আরও বোঝা যাওয়া যাওয়াকারী করতেও পারি। উদাহরণস্বরূপ, Array শ্রেণীকে enqueue() এবং dequeue() নামকরণ দিতে পারি, যারা শুধুমাত্র push() এবং shift() পদ্ধতিকে পুনরায় ব্যবহার করে থাকে:

Array.prototype.enqueue = function(vItem) {
  this.push(vItem);
};
Array.prototype.dequeue = function() {
  return this.shift();
};

TIY

সম্প্রতির পদ্ধতিগুলির সঙ্গে সংযুক্ত না থাকা পদ্ধতি যোগ করা

স্বাভাবিকভাবে, আপনি সম্প্রতির মতো পদ্ধতিগুলির সঙ্গে সংযুক্ত না থাকা পদ্ধতি যোগ করতে পারেন। উদাহরণস্বরূপ, যদি আপনি কোনও আইটেমকে একটি আইটেমের স্থান নির্ধারণ করতে চান, কোনও স্থানীয় পদ্ধতি নেই যা এই কাজটি করতে পারে। আমরা সহজেই নিচের পদ্ধতিটি তৈরি করতে পারি:

Array.prototype.indexOf = function (vItem) {
  for (var i=0; i<this.length; i++) {
    if (vItem == this[i]) {
	  return i;
	}
  }
  return -1;
}

এই indexOf() পদ্ধতি String শ্রেণীর একই নামভুক্ত পদ্ধতির সঙ্গে একই অভিব্যক্তি রাখে, একটি আইটেমকে তাৎক্ষণিকভাবে খুঁজে পাওয়া যাবে, যখন একটি অসময় পর্যন্ত একটি পাওয়া যাওয়া আইটেম ক্রমাগত পর্যালোচনা করা হয়। যদি একটি একই আইটেম পাওয়া যায়, তবে সেটির স্থান ফিরে দেওয়া হবে, না তবে -1 ফিরে দেওয়া হবে। এই নির্দিষ্ট সংজ্ঞার সাথে, আমরা নিচের কোডটি লিখতে পারি:

var aColors = new Array("red","green","blue");
alert(aColors.indexOf("green"));	//输出 "1"

TIY

为本地对象添加新方法

最后,如果想给 ECMAScript 中每个本地对象添加新方法,必须在 Object 对象的 prototype 属性上定义它。前面的章节我们讲过,所有本地对象都继承了 Object 对象,所以对 Object 对象做任何改变,都会反应在所有本地对象上。例如,如果想添加一个用警告输出对象的当前值的方法,可以采用下面的代码:

Object.prototype.showValue = function () {
  alert(this.valueOf());
};
var str = "hello";
var iNum = 25;
str.showValue();		//输出 "hello"
iNum.showValue();		//输出 "25"

TIY

这里,String 和 Number 对象都从 Object 对象继承了 showValue() 方法,分别在它们的对象上调用该方法,将显示 "hello" 和 "25"。

重定义已有方法

就像能给已有的类定义新方法一样,也可重定义已有的方法。如前面的章节所述,函数名只是指向函数的指针,因此可以轻松地指向其他函数。如果修改了本地方法,如 toString(),会出现什么情况呢?

Function.prototype.toString = function() {
  return "Function code hidden";
}

前面的代码完全合法,运行结果完全符合预期:

function sayHi() {
  alert("hi");
}
alert(sayHi.toString());	//输出 "Function code hidden"

TIY

也许你还记得,Function 对象这一章中介绍过 Function 的 toString() 方法通常输出的是函数的源代码。覆盖该方法,可以返回另一个字符串(在这个例子中,可以返回 "Function code hidden")。不过,toString() 指向的原始函数怎么了呢?它将被无用存储单元回收程序回收,因为它被完全废弃了。没有能够恢复原始函数的方法,所以在覆盖原始方法前,比较安全的做法是存储它的指针,以便以后的使用。有时你甚至可能在新方法中调用原始方法:

Function.prototype.originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
  if (this.originalToString().length > 100) {
    return "Function too long to display.";
  } else {
    return this.originalToString();
  }
};

TIY

এই কোডটিতে, প্রথম লাইনটি বর্তমান toString() পদ্ধতিটির উল্লেখ সংরক্ষণ করে originalToString অপারেটরে।এরপর একটি অভিন্ন পদ্ধতির মাধ্যমে toString() পদ্ধতিকে পরিবর্তন করা হয়।নতুন পদ্ধতি এই পদ্ধতির সূত্রকে পরীক্ষা করবে, যদি তা শত বাক্যবন্ধনীর উপর বেশি হয়, তবে একটি ত্রুটি সংকেত প্রদান করবে, যাতে বলা হয় যে পদ্ধতির সূত্রটি খুবই দীর্ঘ, না তবে originalToString() পদ্ধতিকে ব্যবহার করে পদ্ধতির সূত্রকে প্রদান করবে。

অতি পরবর্তী বাঁধা (Very Late Binding)

প্রযুক্তিগতভাবে, অতি পরবর্তী বাঁধা নেই।এই বইটি এই শব্দটি ব্যবহার করে ECMAScript-এর একটি ঘটনা বর্ণনা করে, যেখানে অবজেক্টটির প্রতিস্থাপনকরা হলেও তার পদ্ধতিটি নির্বাচন করা সম্ভব।উদাহরণস্বরূপ:

var o = new Object();
Object.prototype.sayHi = function () {
  alert("hi");
};
o.sayHi();

TIY

অধিকাংশ প্রোগ্রামিং ভাষায়, অবজেক্টটির প্রতিস্থাপন করা আগেই অবজেক্টের পদ্ধতিটি নির্বাচন করতে হয়।এখানে, method sayHi() একটি Object শ্রেণীর একটি প্রতিস্থাপন তৈরির পরে যুক্ত করা হয়।ক্লাসিক্যাল ভাষায় এই কাজটির কোনও প্রতিবেদন নেই, এবং এই পদ্ধতিটি সরাসরি Object অবজেক্টের প্রতিস্থাপনকে প্রদান করা এবং তা ব্যবহার করা সম্ভব (পরবর্তী সূত্রে)।

নোট:অসুবিধাজনক পদ্ধতির ব্যবহার না করা সুপারিশ করা হয়, কারণ তা পর্যবেক্ষণ এবং রেকর্ড করা খুবই কঠিন।কিন্তু, এই সম্ভাবনা সম্পর্কে জানা উচিত。