2015-12-08 9 views
5

तो मैं जावास्क्रिप्ट का उपयोग कर प्रोटोटाइप सीख रहा हूँ, और कुछ कोड की कोशिश की। क्या इस परिणाम का कोई कारण है?अपरिभाषित परिणाम का उपयोग कर प्रोटोटाइप [जावास्क्रिप्ट]

मैंने कई परीक्षण किए हैं। मैंने निष्कर्ष निकाला है कि प्रोटोटाइप ऑब्जेक्ट को पुन: असाइन करने से कर्मचारी वर्ग के किसी भी पहले बनाए गए उदाहरण नए नियत प्रोटोटाइप के अंदर पाए गए किसी भी गुण तक पहुंचने में असमर्थ होते हैं। क्या यह सही है?

+3

जब आप कोई उदाहरण बनाते हैं तो उस समय निर्माता के प्रोटोटाइप का संदर्भ लेता है। यदि आप बाद में प्रोटोटाइप को प्रतिस्थापित करते हैं, तो मौजूदा उदाहरण उस पर प्रतिबिंबित नहीं होंगे। एक बार जब आप एक उदाहरण बना लेते हैं, तो आमतौर पर यह अपेक्षा की जाती है कि आप इसे बदलने के बजाय प्रोटोटाइप का विस्तार करेंगे। –

+5

प्रोटोटाइप ऑब्जेक्ट का उदाहरण का संदर्भ निर्माण समय पर सेट किया गया है (यानी 'नया' वाला लाइन)। पूरे 'Foo.prototype' प्रॉपर्टी ऑब्जेक्ट को बदलना इस संदर्भ को बाद में इस संदर्भ में नहीं बदलेगा। हालांकि, 'Foo.prototype' ऑब्जेक्ट _will_ में परिवर्तन देखा जाना चाहिए (क्योंकि यह वही ऑब्जेक्ट है), इसलिए उदा। यदि आपने इसके बजाय 'कर्मचारी.प्रोटोटाइप.इस वर्किंग = सत्य' किया है, तो आप देखेंगे कि आप –

+0

की अपेक्षा करते हैं कि आगे पढ़ने के लिए, यह प्रोटोटाइप विरासत का वास्तव में अच्छा प्रदर्शन है: http://markdalgleish.com/2012/10/a -टच-ऑफ-क्लास-विरासत-इन-जावास्क्रिप्ट/ – br3nt

उत्तर

1

सबसे पहले, इससे पहले कि आप Employee का एक उदाहरण बनाया है आप प्रोटोटाइप सेट करते हैं, ताकि ऑब्जेक्ट को नए प्रोटोटाइप मानों को विरासत में नहीं मिला हो।

अगला, आपके द्वारा प्रोटोटाइप सेट करने के बाद बनाए गए किसी भी ऑब्जेक्ट को नए प्रोटोटाइप ऑब्जेक्ट का वारिस होगा।

आखिरकार, working संपत्ति के बजाय ऑब्जेक्ट में isWorking संपत्ति होगी।

तो अपने उदाहरण फिर से करें:

function Employee(name) { this.name= name; }; 

var m1 = new Employee("Bob"); 

var working= { isWorking: true }; 
Employee.prototype = working; 

var m2 = new Employee("Sam"); 

alert(m1.isWorking); // undefined 
alert(m2.isWorking); // true 
2

प्रोटोटाइप बदलने से पहले से बनाए गए ऑब्जेक्ट को प्रभावित नहीं होगा। यह केवल उस वस्तु के आधार पर बनाई गई वस्तुओं को प्रभावित करेगा।

एक संपत्ति __proto__ है जिसका उपयोग प्रोटोटाइप को बदलने के लिए किया जा सकता है, लेकिन इसके कार्यान्वयन की आवश्यकता नहीं है। ES6 प्रोटोटाइप को बदलने के लिए setPrototypeOf विधि को परिभाषित करता है, लेकिन चूंकि यह केवल ES6 में है, समर्थन भिन्न हो सकता है।

1

सरल फिक्स इसे ठीक से असाइन करना है। इसके साथ चारों ओर यहाँ खेलने:

function Employee(name) { 
    this.name = name; 
} 
var m = new Employee("Bob"); 
var working = { 
    isWorking: true 
}; 
Employee.prototype.working = working; 
alert(m.working.isWorking); 

कई कर्मचारियों के लिए एक बेहतर ठीक एक वर्ग है, तो इस बात का उदाहरण बना बनाने के लिए है http://jsfiddle.net/MarkSchultheiss/p6jyqbgv/1/

"use strict"; 
function makeClassStrict() { 
    var isInternal, instance; 
    var constructor = function(args) { 
    if (this instanceof constructor) { 
     if (typeof this.init == "function") { 
     this.init.apply(this, isInternal ? args : arguments); 
     } 
    } else { 
     isInternal = true; 
     instance = new constructor(arguments); 
     isInternal = false; 
     return instance; 
    } 
    }; 
    return constructor; 
} 
var EmployeeClass = makeClassStrict(); 
EmployeeClass.prototype.init = function(employeeName, isWorking) { 
    var defaultName = 'notbob'; 
    this.name = employeeName ? employeeName : defaultName; 
    this.working = !!isWorking; 
}; 
// call this to get the name property 
EmployeeClass.prototype.getName = function() { 
    return this.name 
}; 
//note no "new" needed due to the makeClassStrict that does that 
var m = EmployeeClass("Bob"); 
alert(m.working +":"+ m.name); 
m.working = true; 
alert(m.working +":"+ m.name); 
var notbob = EmployeeClass("Charlie",false); 
alert(notbob.working +":"+ notbob.name); 
alert(notbob.getName()+ m.getName()); 
1

आप पूरे प्रोटोटाइप संपत्ति ओवरराइड नहीं कर सकते और पहले से ही विद्यमान उदाहरणों काम करने की उम्मीद। जावास्क्रिप्ट उस तरह से काम नहीं करता है। लेकिन आप प्रोटोटाइप ऑब्जेक्ट के माध्यम से लूप कर सकते हैं और पहले से सेट की गई किसी भी चीज को अनसेट कर सकते हैं, फिर अपनी नई ऑब्जेक्ट के माध्यम से लूप कर सकते हैं और इसे किसी और चीज़ पर सेट कर सकते हैं।

function Employee(name) { this.name= name; } 
var m = new Employee("Bob"); 
var working= { isWorking: true }; 
for(var j in Employee.prototype){delete Employee.prototype[j];}//unset all properties, the same as setting to {} 
for(j in working){Employee.prototype[j]=working[j];}//set the properties 
alert(m.isWorking); 
+0

आप वास्तव में ऐसा नहीं कर सकते हैं, क्योंकि प्रोटोटाइप के स्पष्ट रूप से घोषित विशेषताओं को 'हटाएं' कीवर्ड का उपयोग करके हटाया नहीं जा सकता है। –

+0

@ Æðelstan अपने लिए देखें: http://jsfiddle.net/L2yvjtow/ – Ultimater

+0

यह काम करता है, अच्छा बिंदु! –

संबंधित मुद्दे