2010-01-21 10 views
7

o.prototype = {...} केवल तभी काम कर रहा है जब ओ एक कार्य है। मान लीजिए मैं निम्नलिखित कोडजावास्क्रिप्ट प्रोटोटाइप कार्यों तक सीमित है?

conf = { 
    a: 2, 
    b: 4 
}; 
conf.prototype = { 
    d: 16 
} 

conf.a और conf.b ठीक है और उचित मूल्यों वापस भेजता है। लेकिन conf.d 16 वापस नहीं आता है बल्कि यह अपरिभाषित है। क्या कोई समाधान चूसता है कि इस प्रकार के ऑब्जेक्ट्स पर प्रोटोटाइप आधारित सामान्यीकरण भी लागू किया जा सकता है।

उत्तर

21

आप prototype संपत्ति है कि Constructor Functions पर इस्तेमाल किया जा सकता और आंतरिक[[Prototype]] संपत्ति भ्रमित कर रहे हैं।

सभी वस्तुओं इस आंतरिक [[Prototype]] संपत्ति है, और केवल new ऑपरेटर जब आप एक निर्माता समारोह से कॉल करने की यह स्थापित करने के लिए ([[Construct]] आंतरिक ऑपरेशन के माध्यम से) की अनुमति दी है।

// Check if native implementation available 
if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
    function F() {} // empty constructor 
    F.prototype = o; // set base object as prototype 
    return new F(); // return empty object with right [[Prototype]] 
    }; 
} 

var confProto = { 
    d: 16 
}; 
var conf = Object.create(confProto); 
conf.a = 2; 
conf.b = 4; 

:

आप वस्तु उदाहरणों के साथ मूलरूप विरासत (कंस्ट्रक्टर्स का उपयोग किए बिना) करना चाहते हैं, Crockford के Object.create तकनीक आप क्या चाहते हैं (है कि विधि अब हाल ही में मंजूरी दे दी ECMAScript 5 वें संस्करण का हिस्सा है) है उपरोक्त कोड में conf इसके तीन सदस्यों को होगा, लेकिन केवल a और b इच्छा उस पर शारीरिक रूप से मौजूद है:

conf.hasOwnProperty('a'); // true 
conf.hasOwnProperty('b'); // true 
conf.hasOwnProperty('d'); // false 

क्योंकि d conf [[Prototype]] (confProto) पर मौजूद है।

property accessors, . और [] गुण अप अगर प्रोटोटाइप श्रृंखला ([[Get]] आंतरिक विधि के माध्यम से) में आवश्यक देख हल करने जिम्मेदार हैं।

+3

क्या डाउनवॉटर कृपया कोई टिप्पणी छोड़ सकता है? मैं हमेशा अपने उत्तरों को सुधारने के लिए देख रहा हूँ :) – CMS

6

वास्तव जावास्क्रिप्ट में "प्रोटोटाइप" के दो विभिन्न प्रकार हैं:

  1. एक "छिपा" लिंक हर वस्तु है (के [[Prototype]] का उपयोग इस छिपा लिंक प्रतिनिधित्व करने के लिए करते हैं)। डिफ़ॉल्ट रूप से ऑब्जेक्ट लिटरल में उनके छिपे हुए लिंक Object.prototype पर इंगित करते हैं, फ़ंक्शन ऑब्जेक्ट्स का अपना छिपी हुई लिंक Function.prototype पर इंगित करती है, और सरणी के पास Array.prototype पर इशारा होता है। ये छिपे प्रोटोटाइप लिंक नाम "प्रोटोटाइप" वाले गुणों से संबंधित नहीं हैं। आप o.prototype जोड़कर या संशोधित करके इन छिपे हुए लिंक को नहीं बदल सकते हैं।
  2. दूसरा यह है कि सभी फ़ंक्शन ऑब्जेक्ट्स में स्वचालित रूप से "prototype" नामक एक विशेष संपत्ति होती है। यह मुख्य रूप से कन्स्ट्रक्टर आमंत्रण पैटर्न के उपयोग के लिए है।

[[Prototype]] गुण खोज के लिए प्रयोग किया जाता है, जब भी एक संपत्ति एक वस्तु में नहीं पाया जा सकता (शास्त्रीय पदानुक्रम में माता-पिता की तरह), उसके [[Prototype]] बजाय खोजा गया है।एक उपयोग परिदृश्य: कहें कि आप सभी ऑब्जेक्ट्स में एक संपत्ति जोड़ना चाहते हैं, तो आप इसे Object.prototype पर जोड़ सकते हैं जो स्वचालित रूप से सभी ऑब्जेक्ट्स पर लागू होगा क्योंकि सभी ऑब्जेक्ट्स Object.prototype उनके [[Prototype]] चेन रूट के रूप में हैं।

चलिए ऑब्जेक्ट्स 'prototype "संपत्ति पर वापस आते हैं। यह केवल तब उपयोगी होता है जब ऑपरेटर new के साथ उपयोग किया जाता है। एक उदाहरण के रूप निम्नलिखित कोड का टुकड़ा लें:

function F() {} // function declaration 
// F now has a property named "prototype" 

var f = new F(); // use "new" operator to create a new function object based on F 

क्या new F() ऊपर करता है पहले एक नया कार्य वस्तु बनाने के लिए, F.prototype होने के लिए इस नव निर्मित समारोह वस्तु की [[Prototype]] (छुपा लिंक) सेट किया गया है, और फिर लौट नया समारोह वस्तु। यह संभवतः आप पहले से ही समझते हैं कि फ़ंक्शन ऑब्जेक्ट्स के लिए काम करता है।

याद रखें कि मैंने कहा है कि हम ऑब्जेक्ट्स [[Prototype]] नहीं बदल सकते हैं? खैर, कम से कम सीधे नहीं। क्रॉकफ़ोर्ड का Object.create फ़ंक्शन केवल इस तथ्य का उपयोग करके करता है कि ऑपरेटर new हमारे लिए [[Prototype]] सेट करने में मदद कर सकता है। तो Object.create का उपयोग करके, आप जानबूझकर संकेत देते हैं कि आपकी नई वस्तु के छिपे हुए लिंक को इंगित करना चाहिए। (कुछ हद तक यह दर्शाता है कि आपकी मूल कक्षा कौन है)

आपके उदाहरण में, conf एक ऑब्जेक्ट शाब्दिक है और conf.prototype वास्तव में उपयोगी नहीं है। यहाँ एक और संस्करण शास्त्रीय शैली का उपयोग है:

function ConfBase() {} 
ConfBase.prototype.d = 16; 
var conf = new ConfBase(); 
conf.a = 2; 
conf.b = 4; 

document.writeln(conf.a); 
document.writeln(conf.b); 
document.writeln(conf.d); 

@CMS के जवाब की तुलना में, मैं Object.create का उपयोग करना पसंद करते हैं। लेकिन अनिवार्य रूप से 2 शैलियों एक ही अंतर्निहित तंत्र का उपयोग कर रहे हैं, बस Object.create इसे साफ करने में मदद करता है।

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