जबकि यहां कई लोग कहते हैं कि ऑब्जेक्ट निर्माण के लिए कोई सबसे अच्छा तरीका नहीं है, एक तर्क है कि क्यों जावास्क्रिप्ट में 2019 तक ऑब्जेक्ट बनाने के लिए बहुत सारे तरीके हैं, और यह विभिन्न पुनरावृत्तियों पर जावास्क्रिप्ट की प्रगति के साथ करना है EcmaScript की 1997 में वापस डेटिंग जारी हुई।
ईसीएमएस्क्रिप्ट 5 से पहले, ऑब्जेक्ट बनाने के केवल दो तरीके थे: कंस्ट्रक्टर फ़ंक्शन या शाब्दिक अंकन (नई वस्तु का बेहतर विकल्प) ()। कंस्ट्रक्टर फ़ंक्शन संकेतन के साथ आप एक ऑब्जेक्ट बनाते हैं जिसे कई उदाहरणों में (नए कीवर्ड के साथ) इंस्टेंट किया जा सकता है, जबकि शाब्दिक अंकन एकल ऑब्जेक्ट को सिंगलटन की तरह वितरित करता है।
// constructor function
function Person() {};
// literal notation
var Person = {};
आपके द्वारा उपयोग की जाने वाली विधि के बावजूद, जावास्क्रिप्ट ऑब्जेक्ट्स मुख्य मूल्य जोड़े के गुण हैं:
// Method 1: dot notation
obj.firstName = 'Bob';
// Method 2: bracket notation. With bracket notation, you can use invalid characters for a javascript identifier.
obj['lastName'] = 'Smith';
// Method 3: Object.defineProperty
Object.defineProperty(obj, 'firstName', {
value: 'Bob',
writable: true,
configurable: true,
enumerable: false
})
// Method 4: Object.defineProperties
Object.defineProperties(obj, {
firstName: {
value: 'Bob',
writable: true
},
lastName: {
value: 'Smith',
writable: false
}
});
जावास्क्रिप्ट के शुरुआती संस्करणों में, वर्ग-आधारित विरासत की नकल करने का एकमात्र वास्तविक तरीका निर्माण कार्यों का उपयोग करना था। कंस्ट्रक्टर फ़ंक्शन एक विशेष फ़ंक्शन है जो 'नए' कीवर्ड के साथ लगाया जाता है। अधिवेशन द्वारा, फ़ंक्शन पहचानकर्ता को पूंजीकृत किया जाता है, एल्बिएट इसकी आवश्यकता नहीं है। कंस्ट्रक्टर के अंदर, हम उस ऑब्जेक्ट में प्रॉपर्टी को जोड़ने के लिए 'इस' कीवर्ड का उल्लेख करते हैं, जो कंस्ट्रक्टर फ़ंक्शन का निर्माण कर रहा है। जब तक आप स्पष्ट रूप से रिटर्न कीवर्ड का उपयोग नहीं करते हैं और कुछ और लौटाते हैं, तब तक निर्माता कार्य को स्पष्ट रूप से कॉल किए गए फ़ंक्शन पर वापस जाने वाली आबादी वाले गुणों के साथ नई वस्तु देता है।
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.sayName = function(){
return "My name is " + this.firstName + " " + this.lastName;
}
}
var bob = new Person("Bob", "Smith");
bob instanceOf Person // true
SayName विधि के साथ एक समस्या है। आमतौर पर, ऑब्जेक्ट-ओरिएंटेड क्लास-आधारित प्रोग्रामिंग भाषाओं में, आप ऑब्जेक्ट बनाने के लिए कारखानों के रूप में कक्षाओं का उपयोग करते हैं। प्रत्येक ऑब्जेक्ट के अपने स्वयं के उदाहरण चर होंगे, लेकिन इसमें क्लास ब्लूप्रिंट में परिभाषित विधियों का एक संकेतक होगा। दुर्भाग्य से, जावास्क्रिप्ट के निर्माता फ़ंक्शन का उपयोग करते समय, हर बार इसे कॉल करने पर, यह नए बनाए गए ऑब्जेक्ट को नए बनाए गए ऑब्जेक्ट पर परिभाषित करेगा। इसलिए प्रत्येक वस्तु का अपना एक अलग नामनाम गुण होगा। यह अधिक स्मृति संसाधनों का उपभोग करेगा।
स्मृति संसाधनों में वृद्धि के अलावा, निर्माण कार्य के अंदर तरीकों को परिभाषित करना विरासत की संभावना को समाप्त करता है। फिर से, विधि को नए बनाए गए ऑब्जेक्ट और किसी अन्य ऑब्जेक्ट पर एक संपत्ति के रूप में परिभाषित किया जाएगा, इसलिए विरासत की तरह काम नहीं कर सकता है। इसलिए, जावास्क्रिप्ट जावास्क्रिप्ट के रूप में प्रोटोटाइप श्रृंखला प्रदान करता है, जिससे जावास्क्रिप्ट एक प्रोटोटाइप भाषा बन जाती है।
यदि आपके पास माता-पिता हैं और माता-पिता बच्चे के कई गुणों को साझा करते हैं, तो बच्चे को उन गुणों को प्राप्त करना चाहिए। ES5 से पहले, यह निम्नानुसार पूरा किया गया था:
function Parent(eyeColor, hairColor) {
this.eyeColor = eyeColor;
this.hairColor = hairColor;
}
Parent.prototype.getEyeColor = function() {
console.log('has ' + this.eyeColor);
}
Parent.prototype.getHairColor = function() {
console.log('has ' + this.hairColor);
}
function Child(firstName, lastName) {
Parent.call(this, arguments[2], arguments[3]);
this.firstName = firstName;
this.lastName = lastName;
}
Child.prototype = Parent.prototype;
var child = new Child('Bob', 'Smith', 'blue', 'blonde');
child.getEyeColor(); // has blue eyes
child.getHairColor(); // has blonde hair
जिस तरह से हमने ऊपर प्रोटोटाइप श्रृंखला का उपयोग किया है, उसमें एक विचित्रता है। चूंकि प्रोटोटाइप एक लाइव लिंक है, इसलिए प्रोटोटाइप चेन में किसी एक ऑब्जेक्ट की प्रॉपर्टी को बदलकर, आप उसी ऑब्जेक्ट की दूसरी प्रॉपर्टी को भी बदल रहे होंगे। जाहिर है, बच्चे की विरासत में मिली विधि को बदलने से माता-पिता के तरीके को नहीं बदलना चाहिए। Object.create ने पॉलीफ़िल का उपयोग करके इस समस्या को हल किया। इस प्रकार, Object.create के साथ, आप प्रोटोटाइप श्रृंखला में माता-पिता की समान संपत्ति को प्रभावित किए बिना किसी बच्चे की संपत्ति को प्रोटोटाइप श्रृंखला में सुरक्षित रूप से संशोधित कर सकते हैं।
ECMAScript 5 ने ऑब्जेक्ट क्रिएशन के लिए कंस्ट्रक्टर फंक्शन में उपरोक्त बग को हल करने के लिए Object.create की शुरुआत की। Object.create () विधि नई बनी हुई वस्तु के प्रोटोटाइप के रूप में एक मौजूदा वस्तु का उपयोग करके एक नई वस्तु बनाती है। चूंकि एक नई वस्तु बनाई गई है, अब आपके पास समस्या नहीं है जहां प्रोटोटाइप श्रृंखला में बाल संपत्ति को संशोधित करना श्रृंखला में उस संपत्ति के माता-पिता के संदर्भ को संशोधित करेगा।
var bobSmith = {
firstName: "Bob",
lastName: "Smith",
sayName: function(){
return "My name is " + this.firstName + " " + this.lastName;
}
}
var janeSmith = Object.create(bobSmith, {
firstName : { value: "Jane" }
})
console.log(bobSmith.sayName()); // My name is Bob Smith
console.log(janeSmith.sayName()); // My name is Jane Smith
janeSmith.__proto__ == bobSmith; // true
janeSmith instanceof bobSmith; // Uncaught TypeError: Right-hand side of 'instanceof' is not callable. Error occurs because bobSmith is not a constructor function.
ES6 से पहले, फ़ंक्शन रचनाकारों और Object.create का उपयोग करने के लिए यहां एक सामान्य रचनात्मक पैटर्न था:
const View = function(element){
this.element = element;
}
View.prototype = {
getElement: function(){
this.element
}
}
const SubView = function(element){
View.call(this, element);
}
SubView.prototype = Object.create(View.prototype);
अब निर्माण कार्यों के साथ युग्मित Object.create को जावास्क्रिप्ट में ऑब्जेक्ट निर्माण और विरासत के लिए व्यापक रूप से उपयोग किया गया है। हालांकि, ईएस 6 ने कक्षाओं की अवधारणा को पेश किया, जो मुख्य रूप से जावास्क्रिप्ट के मौजूदा प्रोटोटाइप-आधारित विरासत पर सिंथेटिक चीनी हैं। वर्ग सिंटैक्स जावास्क्रिप्ट में एक नया ऑब्जेक्ट-ओरिएंटेड इनहेरिटेंस मॉडल पेश नहीं करता है। इस प्रकार, जावास्क्रिप्ट एक प्रोटोटाइप भाषा है।
ईएस 6 कक्षाएं विरासत को बहुत आसान बनाती हैं। अब हमें मूल कक्षा के प्रोटोटाइप फ़ंक्शंस को मैन्युअल रूप से कॉपी करना होगा और चाइल्ड क्लास के कंस्ट्रक्टर को रीसेट करना होगा।
// create parent class
class Person {
constructor (name) {
this.name = name;
}
}
// create child class and extend our parent class
class Boy extends Person {
constructor (name, color) {
// invoke our parent constructor function passing in any required parameters
super(name);
this.favoriteColor = color;
}
}
const boy = new Boy('bob', 'blue')
boy.favoriteColor; // blue
सभी में, जावास्क्रिप्ट में ऑब्जेक्ट क्रिएशन की इन 5 अलग-अलग रणनीतियों ने एक्मास्क्रिप्ट मानक के विकास को प्रभावित किया।