2015-07-10 8 views
7

जो मुझे पता है कि एक फ़ंक्शन को prototype ऑब्जेक्ट से गुणों का उत्तराधिकारी होना चाहिए, जिसे .prototype या __proto__ संपत्ति का उपयोग करके एक्सेस किया जा सकता है।__proto__ और प्रोटोटाइप अंतर

//my prototype Object 
var myObj = { 
    a: 1, 
    b: 2 
}; 

var myFunc = function() {}; 

// setting function's `prototype` property 
myFunc.prototype = myObj; 
alert(myFunc.a); 
//returns undefined (Why???) I was expecting 1 

लेकिन जब मैं निम्नलिखित की कोशिश की,

//setting function __proto__ property 
myFunc.__proto__ = myObj; 
//returns 1 
alert(myFunc.a); 

तो इसे क्यों काम करता है जब मैं myFunc.__proto__ सेट और नहीं जब मैं myFunc.prototype सेट?

मैंने __proto__ VS. prototype in JavaScript का संदर्भ दिया लेकिन पता नहीं लगा सका।

+2

http://es5.github.io/ बिल्कुल '__proto__' के बारे में कुछ भी नहीं जानता है। जिसका अर्थ है कि यह मानक का हिस्सा नहीं है और आपको इसका कभी भी उपयोग नहीं करना चाहिए। – zerkms

+0

नहीं, किसी ऑब्जेक्ट का प्रोटोटाइप (जिसे इसके साथ विरासत में मिला है) ** ** नहीं है। प्रोप्रोटाइप'। क्या आपने http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript के सभी उत्तरों को पढ़ा है? आपने विशेष रूप से क्या नहीं समझा (हम उन्हें सुधारने में प्रसन्न हैं)? – Bergi

+0

तो प्रोप्रोटाइप के लिए क्या उपयोग किया जाता है ?? – Flake

उत्तर

15

__proto__

आप वास्तव में __proto__ के साथ एक वस्तु के आंतरिक [[Prototype]] संपत्ति पहुँच सकते हैं। आप विरासत पदानुक्रम में वर्तमान वस्तु के वास्तविक अभिभावक के रूप में [[Prototype]] के बारे में सोच सकते हैं।

prototype

यह एक विशेष संपत्ति है, जब एक (निर्माता) समारोह वस्तु, निर्माता से बनाए गए उदाहरणों के लिए विरासत श्रृंखला स्थापित करने के लिए प्रयोग किया जाता है पर निर्धारित किया है। उदाहरण के लिए,

function Foo() {} 
Foo.prototype = {a: 1}; 

अब, जब आप प्रकार Foo की एक नई वस्तु बनाने, नव निर्मित वस्तु के आंतरिक [[Prototype]] संपत्ति Foo.prototype वस्तु संदर्भित करेंगे। आपको लगता है कि इस

console.assert((new Foo()).__proto__ === Foo.prototype); 

आपके मामले में की तरह इस बात की पुष्टि कर सकते हैं,

myFunc.prototype = myObj; 

आप समारोह वस्तु पर एक prototype संपत्ति पैदा कर रहे हैं और इस ही उपयोग किया जाएगा जब आप के साथ नई वस्तुओं का निर्माण कर रहे यह फ़ंक्शन (कन्स्ट्रक्टर फ़ंक्शन)। आप इसे नई वस्तुओं के लिए टेम्पलेट के रूप में सोचना चाहेंगे। इसलिए, जब आप myFunc.a करते हैं, तो जेएस इंजन amyFunc और उसके माता-पिता प्रोटोटाइप श्रृंखला में खोजने की कोशिश करता है और इसे नहीं मिलता है, यही कारण है कि यह undefined देता है।

लेकिन, जब तुम

myFunc.__proto__ = myObj; 

आप myFunc की मूल सेट कर रहे हैं, प्रोटोटाइप श्रृंखला में, myObj करने के लिए। इसलिए, जब आप myFunc.a करते हैं, तो जेएस इंजन पहले amyFunc ऑब्जेक्ट में खोजने की कोशिश करता है, और यह वहां नहीं है। इसलिए, यह इसे अपने तत्काल माता-पिता में ढूंढने का प्रयास करता है, जो myObj है। यही कारण है कि इस मामले में यह 1 देता है।


नोट: आप निम्न समारोह प्रोटोटाइप श्रृंखला को समझने के लिए उपयोग कर सकते हैं बेहतर

function printPrototypeChain(object) { 
    while (object !== null) { 
     console.log(object); 
     object = Object.getPrototypeOf(object); 
    } 
} 

अब, हम प्रोटोटाइप श्रृंखला मुद्रित करते हैं जब वस्तु समारोह के prototype संपत्ति के रूप में सेट किया गया है वस्तु।

function myFunc() {} 
myFunc.prototype = { 
    a: 1, 
    b: 2 
}; 
printPrototypeChain(myFunc); 

उत्पादन इतना undefined दिया जाता है हो जाएगा इन वस्तुओं में से

[Function: myFunc] 
[Function: Empty] 
{} 

कोई नहीं a परिभाषित किया गया है,। लेकिन, इस मामले में,

function myFunc() {} 
myFunc.__proto__ = { 
    a: 1, 
    b: 2 
}; 
printPrototypeChain(myFunc); 

प्रोटोटाइप श्रृंखला इस

[Function: myFunc] 
{ a: 1, b: 2 } 
{} 

और a की तरह हो जाता है myFunc के तत्काल माता पिता में पाया जाता है। तो, संबंधित मान 1 वापस कर दिया गया है।

नोट: अपने वास्तविक कोड में __proto__ का उपयोग न करें, क्योंकि इसे पिछड़ा संगतता के लिए जावास्क्रिप्ट विनिर्देश के नवीनतम संस्करणों में रखा गया है। इसके बारे में और पढ़ें here। इसके बजाय Object.getPrototypeOf और Object.setPrototypeOf का उपयोग करें।

+1

एक समारोह के लिए दो प्रोटोटाइप ...... उलझन में बिल्लियों !!! – Flake

+0

जब आप myFunc.prototype = myObj करते हैं; myObj myFunc उदाहरणों के लिए उपलब्ध है, न कि myFunc के लिए यह स्वयं। var x = new myFunc(); console.log (x.a); // रिटर्न 1 – prgmrDev

0

आप एक उदाहरण myFunc की साथ myFunc है, जो एक निर्माता है, भ्रमित कर रहे हैं।

आप कुछ इस तरह करते हैं:

var o = new myFunc(); 
alert(o.a); 

यह सूचित करेंगे क्योंकि 1 o, myFunc का एक उदाहरण है इसलिए इसकी a संपत्ति myFunc प्रोटोटाइप से आता है।

यदि आप __proto__ सेट करते हैं, तो आप सचमुच फ़ंक्शन प्रोटोटाइप को स्वैप कर रहे हैं कि myFunc पहले से विरासत में था और इसे आपके प्रोटोटाइप ऑब्जेक्ट से बदल रहा था। असल में, ऐसा करने के बाद, call जैसे कार्यों पर आप आमतौर पर उपयोग कर सकते हैं, myFunc पर नहीं मिलेगा।

myFunc.__proto__ = myObj; 
myFunc.call(null); // Will throw an error 
0

सभी जेएस ऑब्जेक्ट्स __proto__ सिस्टम प्रॉपर्टी हैं। यदि आप a ऑब्जेक्ट का x मान प्राप्त करने का प्रयास करते हैं, तो सबसे पहले यह संपत्ति ऑब्जेक्ट a गुणों के बीच खोजी जाती है। यदि कुछ भी नहीं मिला तो संपत्ति a.__proto__ peroperties के बीच खोज की जाएगी। और इसी तरह। यही कारण है कि myFunc.a ruturns 1 आपके उदाहरण में। जब आप myFunc.prototype=myObj सेट मतलब यह है कि जब आप myFunc का उदाहरण बना है कि myObj भविष्य में उपयोग किया जाएगा:

var mf = new myFunc(); 

और मतलब नहीं है कि कि myFunc, a protpery ही होना चाहिए जैसा कि मैंने ऊपर कहा गया है।

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