ईसीएमएसक्रिप्ट ओब्जेक्ट संशोधन

ECMAScript का उपयोग करके, केवल ऑब्जेक्ट बनाने के बजाय, पहले से मौजूदा ऑब्जेक्ट के व्यवहार को संशोधित किया जा सकता है।

prototype गुण केवल निर्माण फ़ंक्शन के गुण और विधियों को परिभाषित करने के लिए नहीं है, बल्कि स्थानीय ऑब्जेक्ट को गुण और विधियां जोड़ने के लिए भी है।

नई विधि बनाना

मौजूदा विधियों के द्वारा नई विधि बनाना

prototype गुण के माध्यम से किसी भी मौजूदा क्लास के लिए नई विधियाँ परिभाषित की जा सकती हैं, जैसे कि अपनी क्लास के लिए करते हैं। उदाहरण के लिए, आप याद करें कि Number की toString() विधि क्या करती है? यदि इसे 16 के रूप में एक पारामीटर दिया जाता है, तो यह अष्टकोणीय चार्टरिंग करती है। यदि इसके पारामीटर 2 है, तो यह द्विपदी चार्टरिंग करती है। एक विधि को बनाकर, संख्या ऑब्जेक्ट को सीधे अष्टकोणीय स्ट्रिंग में बदल सकते हैं। इस विधि को बनाना बहुत सरल है:

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

इस पर्यावरण में, चिह्न this 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 ऑब्जेक्ट के प्रोटोटाइप प्रॉपर्टी पर परिभाषित करना होगा। पहले अध्याय में हमने बताया है कि सभी स्थानीय ऑब्जेक्ट 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() तरीके को ओवरराइड किया गया है। नई तरीके में, फ़ंक्शन के स्रोत कोड की लंबाई की जाँच की जाती है। यदि लंबाई 100 से अधिक है, तो त्रुटि संदेश वापस किया जाता है कि फ़ंक्शन कोड बहुत लंबा है, अन्यथा originalToString() तरीके को बुलाया जाता है और फ़ंक्शन के स्रोत कोड को वापस किया जाता है।

अत्यधिक लेट बाइंडिंग (Very Late Binding)

तकनीकी रूप से, अत्यधिक लेट बाइंडिंग नहीं है। इस पुस्तक में, ECMAScript में एक ऐसे घटना को वर्णित करने के लिए इस शब्द का इस्तेमाल किया गया है, जो ऑब्जैक्ट को उद्घाटित करने के बाद उसके तरीकों को परिभाषित करने की क्षमता है। उदाहरण के लिए:

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

TIY

अधिकांश कार्यक्रम डिजाइनिंग भाषाओं में, ऑब्जैक्ट को उद्घाटित करने से पहले ऑब्जैक्ट के तरीकों को परिभाषित करना आवश्यक है। यहाँ, method sayHi() को Object की क्लास के एक उदाहरण को बनाने के बाद जोड़ा गया है। पारंपरिक भाषाओं में इस तरह की कार्रवाई के बारे में नहीं सुना गया है, और इस तरीके को Object ऑब्जैक्ट के उदाहरण को स्वचालित रूप से दिया जाता है और तुरंत इस्तेमाल किया जा सकता है (अगले वाक्य के बाद)।

ध्यान:अत्यधिक लेट बाइंडिंग विधि का इस्तेमाल नहीं करना चाहिए, क्योंकि इसका ट्रैकिंग और रिकॉर्ड करना मुश्किल है। हालांकि, इसकी संभावना को जानना चाहिए।