2010-02-11 15 views
17

निम्नलिखित कोड को देखते हुए:मैं जावास्क्रिप्ट ऑब्जेक्ट की प्रोटोटाइप श्रृंखला कैसे देख सकता हूं?

function a() {} 
function b() {} 
b.prototype = new a(); 
var b1 = new b(); 

हम रह सकते हैं कि ab की प्रोटोटाइप श्रृंखला में जोड़ा गया है। महान। और, निम्नलिखित सभी सत्य हैं:

b1 instanceof b 
b1 instanceof a 
b1 instanceof Object 

मेरा प्रश्न है, क्या होगा यदि हम समय से पहले b1 की उत्पत्ति को नहीं जानते हैं? हम इसकी प्रोटोटाइप श्रृंखला के सदस्यों को कैसे खोज सकते हैं? आदर्श रूप में मुझे [b, a, Object] या ["b", "a", "Object"] जैसे सरणी चाहिए।

क्या यह संभव है? मेरा मानना ​​है कि मैंने एसओ पर कहीं जवाब देखा है, जिसने वर्णन किया कि यह कैसे पता लगाया जाए लेकिन मैं अपने जीवन के लिए इसे फिर से नहीं ढूंढ सकता।

उत्तर

2

आप प्रोटोटाइप को खोजने के लिए ऑब्जेक्ट की "कन्स्ट्रक्टर" प्रॉपर्टी का उपयोग कर सकते हैं, और फिर जब तक आप इंद्रधनुष के अंत तक नहीं पहुंच जाते तब तक चेन करें।

function getPrototypes(o) { 
    return (function gp(o, protos) { 
    var c = o.constructor; 
    if (c.prototype) { 
     protos.push(c.prototype); 
     return gp(c.prototype, protos); 
    } 
    return protos; 
    })(o, []); 
} 

(शायद) (अच्छी तरह से बकवास, मुझे लगता है कि यह संभव है, लेकिन उस कोड की अनदेखी) (या शायद :-) मुझे एक सेकंड देना नहीं)

[संपादित करें] वाह इस पूरी तरह से मेरे मन बह रही है - वह कार्य करीब है लेकिन बिल्कुल सही नहीं है; प्रोटोटाइप की एक श्रृंखला स्थापित करना अजीब है और मैं डर और अकेला महसूस कर रहा हूं। मैं सुझाव देता हूं कि उपरोक्त भयानक @ सीएमएस पर ध्यान दें।

+0

'कन्स्ट्रक्टर' आपको निकटतम प्रोटोटाइप पूर्वजों का कन्स्ट्रक्टर फ़ंक्शन देता है जो किसी अन्य कन्स्ट्रक्टर प्रोटोटाइप से विरासत में नहीं मिला है। यह वह बिल्कुल नहीं है जो आप चाहते हैं। उदाहरण के लिए प्रश्न के कोड में, 'b1.constructor' 'a' है, न कि' b', और यदि आपने 'b' से ऑब्जेक्ट' c' प्राप्त किया है, तो 'c1.constructor' अभी भी' a' होगा। अंगूठे का सामान्य नियम: किसी भी चीज़ के लिए 'कन्स्ट्रक्टर' का उपयोग न करें। [eta: lol @ 'डर और अकेला' ... हाँ, यह जावास्क्रिप्ट के उन हिस्सों में से एक है जिसे उपयोगी लगने वाला कुछ ऐसा करके नरक को भ्रमित करने के लिए डिज़ाइन किया गया है लेकिन वास्तव में एक जाल है।] – bobince

+0

हाँ, मैं मूल प्रश्न को एक दिलचस्प अभ्यास पर विचार करें, लेकिन यह ऐसा कुछ नहीं है जिसे मैं कोड में डाल दूंगा जिसे मैं वास्तव में काम करने की उम्मीद करता हूं। यहां एक बहुत अच्छी व्याख्या है: http://mckoss.com/jscript/object।एचटीएम – Pointy

7

ठीक है, ऑब्जेक्ट्स ([[Prototype]]) के बीच प्रोटोटाइप लिंक आंतरिक है, कुछ कार्यान्वयन, मोज़िला की तरह, इसे obj.__proto__ के रूप में बेनकाब करें।

ईसीएमएस्क्रिप्ट 5 वें संस्करण की Object.getPrototypeOf विधि की आवश्यकता है जो आपको चाहिए, लेकिन यह अभी अधिकांश जावास्क्रिप्ट इंजनों पर लागू नहीं किया गया है।

जॉन Resig द्वारा इस implementation करने के लिए एक दृश्य प्रदान करें, यह एक ख़तरा है, यह इंजन के constructor संपत्ति है कि __proto__ का समर्थन नहीं करते पर निर्भर करता है:

if (typeof Object.getPrototypeOf !== "function") { 
    if (typeof "test".__proto__ === "object") { 
    Object.getPrototypeOf = function(object){ 
     return object.__proto__; 
    }; 
    } else { 
    Object.getPrototypeOf = function(object){ 
     // May break if the constructor has been tampered with 
     return object.constructor.prototype; 
    }; 
    } 
} 

याद रखें कि यह नहीं 100% विश्वसनीय है, चूंकि constructor संपत्ति किसी ऑब्जेक्ट पर उत्परिवर्तनीय है।

+2

ऑब्जेक्ट गुणों को देखते हुए जावास्क्रिप्ट में कुछ भी ठीक है और आपको जो भी मिलता है उस पर भरोसा करना जोखिम भरा है :-) – Pointy

+0

धन्यवाद, लेकिन यह मुझे बताता है कि 'ए'' बी 1' का प्रोटोटाइप है लेकिन 'बी' के बारे में कुछ भी नहीं है। मैं कैसे पा सकता हूं कि 'बी 1' 'बी' का उदाहरण है? – pr1001

+0

संभावित प्रोटोटाइप छेड़छाड़ की वजह से 'कन्स्ट्रक्टर' पर वापस गिरना गलत नहीं है, यह शुरू करने में पूरी तरह से गलत है क्योंकि 'कन्स्ट्रक्टर' ऐसा नहीं करता जो आपको लगता है कि यह होगा (नीचे टिप्पणी देखें)। यह Resig से मूल जावास्क्रिप्ट कार्यक्षमता की एक आश्चर्यजनक अज्ञान दिखाता है; ** ** इस स्क्रिप्ट का उपयोग न करें। '__proto__' और' getPrototypeOf' के बारे में जानकारी अच्छी है, हालांकि। – bobince

0

यहाँ एक प्रारंभिक बिंदु है:

Object.prototype.getConstructorNames=function(){ 
     return Object.keys(window).filter(function(e){ 
      return typeof window[e]==="function" && this instanceof window[e]},this) 
    } 

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

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