AngularJS में गुंजाइश प्रोटोटाइप / प्रोटोटाइप विरासत की बारीकियों क्या हैं?


1028

API संदर्भ स्कोप पेज का कहना है:

एक दायरा एक मूल दायरे से विरासत में मिल सकता है

डेवलपर मार्गदर्शिका स्कोप पेज का कहना है:

एक दायरा (प्रोटोटाइपिक रूप से) अपने मूल दायरे से गुण प्राप्त करता है।

  • तो, क्या एक बच्चा गुंजाइश हमेशा प्रोटोटाइप मूल रूप से अपने मूल दायरे से विरासत में मिलती है?
  • क्या इसके कुछ अपवाद हैं?
  • जब यह विरासत में मिलता है, तो क्या यह हमेशा सामान्य जावास्क्रिप्ट प्रोटोटाइप विरासत है?

जवाबों:


1740

त्वरित उत्तर :
एक बच्चे का दायरा सामान्य रूप से मूल रूप से अपने मूल दायरे से विरासत में मिलता है, लेकिन हमेशा नहीं। इस नियम का एक अपवाद इसके साथ एक निर्देश है scope: { ... }- यह एक "अलग" गुंजाइश बनाता है जो प्रोटोटाइपिक रूप से विरासत में नहीं आता है। यह निर्माण अक्सर "पुन: प्रयोज्य घटक" निर्देशन बनाते समय उपयोग किया जाता है।

बारीकियों के लिए, गुंजाइश वंशानुक्रम सामान्य रूप से सीधा होता है ... जब तक आपको बच्चे के दायरे में 2-वे डेटा बाइंडिंग (यानी, तत्व, एनजी-मॉडल) की आवश्यकता नहीं होती है। यदि आप चाइल्ड स्कोप के अंदर से पैरेंट स्कोप में एक आदिम (जैसे, संख्या, स्ट्रिंग, बूलियन) को बांधने की कोशिश करते हैं तो एनजी-रिपीट, एनजी-स्विच और एनजी-शामिल आपको यात्रा कर सकते हैं । यह उस तरह से काम नहीं करता है जिस तरह से अधिकांश लोगों को उम्मीद है कि यह काम करना चाहिए। चाइल्ड स्कोप को अपनी संपत्ति मिलती है जो उसी नाम की मूल संपत्ति को छुपाती है / छाया देती है। आपके वर्कअराउंड हैं

  1. अपने मॉडल के लिए माता-पिता में वस्तुओं को परिभाषित करें, फिर बच्चे में उस वस्तु की एक संपत्ति का संदर्भ दें: parentObj.someProp
  2. $ parent.parentScopeProperty का उपयोग करें (हमेशा संभव नहीं, लेकिन जहां संभव हो वहां 1 से आसान)
  3. पैरेंट स्कोप पर एक फंक्शन को परिभाषित करें, और इसे बच्चे से कॉल करें (हमेशा संभव नहीं)

नई AngularJS डेवलपर्स अक्सर कि एहसास नहीं है ng-repeat, ng-switch, ng-view, ng-includeऔर ng-ifसभी नए बच्चे स्कोप बनाते हैं, तो समस्या अक्सर दिखाई देता है जब इन निर्देशों शामिल हैं। ( समस्या के त्वरित चित्रण के लिए इस उदाहरण को देखें ।)

आदिम के साथ इस मुद्दे को हमेशा 'एक' के "सर्वोत्तम अभ्यास" का पालन करके आसानी से टाला जा सकता है अपने एनजी-मॉडल में - 3 मिनट के मूल्य देखें। Misko के साथ आदिम बाध्यकारी मुद्दे को दर्शाता है ng-switch

होने '।' आपके मॉडल में यह सुनिश्चित होगा कि प्रोटोटाइप विरासत में मिला है। तो, उपयोग करें

<input type="text" ng-model="someObj.prop1">

<!--rather than
<input type="text" ng-model="prop1">`
-->


लंबे उत्तर :

जावास्क्रिप्ट प्रोटोटाइप इनहेरिटेंस

AngularJS wiki पर भी रखा गया: https://github.com/angular/angular.js/wiki/Understanding-Scopes

पहले प्रोटोटाइप प्रोटोटाइप की ठोस समझ होना जरूरी है, खासकर यदि आप सर्वर-साइड बैकग्राउंड से आ रहे हैं और आप क्लास-आइकल इनहेरिटेंस से अधिक परिचित हैं। तो चलिए पहले समीक्षा करते हैं।

मान लीजिए कि पेरेंटस्कोप में एस्ट्रिंज, अम्बर, ऐरे, ऑबजेक्ट और एफंक्शन जैसे गुण हैं। अगर चाइल्डस्कोप प्रोटोटाइप से विरासत में मिला है, तो हमारे पास है:

प्रोटोटाइप विरासत

(ध्यान दें कि अंतरिक्ष को बचाने के लिए, मैं anArrayवस्तु को तीन अलग-अलग ग्रे शाब्दिकों के साथ एक नीली वस्तु के बजाय अपने तीन मूल्यों के साथ एक नीली वस्तु के रूप में दिखाता हूं ।)

यदि हम चाइल्ड स्कोप से पेरेंटस्कोप पर परिभाषित प्रॉपर्टी को एक्सेस करने की कोशिश करते हैं, तो जावास्क्रिप्ट पहले चाइल्ड स्कोप को देखेगा, प्रॉपर्टी को नहीं खोजेगा, उसके बाद इनहेरिटेड स्कोप को देखेगा, और प्रॉपर्टी को ढूंढेगा। (यदि यह पैरेंटस्कोप में प्रॉपर्टी नहीं मिली, तो यह प्रोटोटाइप चेन जारी रहेगा ... रूट स्कोप तक सभी तरह से)। तो, ये सभी सत्य हैं:

childScope.aString === 'parent string'
childScope.anArray[1] === 20
childScope.anObject.property1 === 'parent prop1'
childScope.aFunction() === 'parent output'

मान लीजिए कि हम ऐसा करते हैं:

childScope.aString = 'child string'

प्रोटोटाइप चेन से परामर्श नहीं किया जाता है, और चाइल्डस्कोप में एक नई स्ट्रॉन्ग प्रॉपर्टी जोड़ी जाती है। यह नई प्रॉपर्टी उसी नाम से पेरेंटस्कोप प्रॉपर्टी को छुपाती / छाया देती है। यह बहुत महत्वपूर्ण हो जाएगा जब हम एनजी-रिपीट और एनजी-निचे चर्चा करेंगे।

संपत्ति छिपाना

मान लीजिए कि हम ऐसा करते हैं:

childScope.anArray[1] = '22'
childScope.anObject.property1 = 'child prop1'

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

प्रोटोटाइप श्रृंखला का पालन करें

मान लीजिए कि हम ऐसा करते हैं:

childScope.anArray = [100, 555]
childScope.anObject = { name: 'Mark', country: 'USA' }

प्रोटोटाइप चेन से परामर्श नहीं किया जाता है, और चाइल्ड स्कोप को दो नए ऑब्जेक्ट प्रॉपर्टी मिलती हैं जो समान नामों के साथ पेरेंटस्कोप ऑब्जेक्ट प्रॉपर्टी को छिपाते / छाया देते हैं।

अधिक संपत्ति छिपाना

टेकअवे:

  • यदि हम चाइल्डस्कोप.प्रोपर्टीएक्स पढ़ते हैं, और चाइल्डस्कोप में प्रॉपर्टीएक्स है, तो प्रोटोटाइप चेन से परामर्श नहीं किया जाता है।
  • यदि हम childScope.propertyX सेट करते हैं, तो प्रोटोटाइप श्रृंखला से परामर्श नहीं किया जाता है।

एक अंतिम परिदृश्य:

delete childScope.anArray
childScope.anArray[1] === 22  // true

हमने पहले चाइल्डस्कोप प्रॉपर्टी को डिलीट किया, फिर जब हम प्रॉपर्टी को फिर से एक्सेस करने की कोशिश करते हैं, तो प्रोटोटाइप चेन से सलाह ली जाती है।

बच्चे की संपत्ति को हटाने के बाद


कोणीय घेरा वंशानुक्रम

दावेदार:

  • निम्नलिखित नए स्कोप बनाते हैं, और प्रोटोटाइपिक रूप से इनहेरिट करते हैं: एनजी-रिपीट, एनजी-शामिल, एनजी-स्विच, एनजी-नियंत्रक, निर्देश के साथ scope: true, निर्देश transclude: true
  • निम्नलिखित एक नया दायरा बनाता है जो प्रोटोटाइपिक रूप से विरासत में नहीं मिलता है: साथ निर्देश scope: { ... }। यह इसके बजाय एक "अलग" गुंजाइश बनाता है।

ध्यान दें, डिफ़ॉल्ट रूप से, निर्देश नए दायरे नहीं बनाते हैं - यानी, डिफ़ॉल्ट है scope: false

एनजी-शामिल

मान लें कि हमारे नियंत्रक में है:

$scope.myPrimitive = 50;
$scope.myObject    = {aNumber: 11};

और हमारे HTML में:

<script type="text/ng-template" id="/tpl1.html">
<input ng-model="myPrimitive">
</script>
<div ng-include src="'/tpl1.html'"></div>

<script type="text/ng-template" id="/tpl2.html">
<input ng-model="myObject.aNumber">
</script>
<div ng-include src="'/tpl2.html'"></div>

प्रत्येक एनजी-शामिल में एक नया चाइल्ड स्कोप उत्पन्न होता है, जो मूल रूप से पेरेंट स्कोप से विरासत में प्राप्त होता है।

एनजी-शामिल बच्चे scopes

पहले इनपुट टेक्स्टबॉक्स में टाइपिंग ("77") के कारण बच्चे के दायरे में एक नया myPrimitiveस्कोप प्रॉपर्टी मिलती है जो उसी नाम की पेरेंट स्कोप प्रॉपर्टी को छुपाता / छाया देता है। यह शायद वह नहीं है जो आप चाहते हैं / उम्मीद करते हैं।

एनजी-एक आदिम के साथ शामिल करें

दूसरे इनपुट टेक्स्टबॉक्स में टाइप करने (कहना, "99") का परिणाम नई बाल संपत्ति नहीं है। क्योंकि tpl2.html मॉडल को ऑब्जेक्ट प्रॉपर्टी से बांधता है, जब एनपोडल ऑब्जेक्ट ऑब्जेक्ट myObject के लिए दिखता है, तो प्रोटोटाइप इनहेरिटेंस किक करता है - यह इसे पेरेंट स्कोप में पाता है।

एक वस्तु के साथ एनजी-शामिल

हम $ माता-पिता का उपयोग करने के लिए पहले टेम्पलेट को फिर से लिख सकते हैं, अगर हम अपने मॉडल को आदिम से वस्तु में बदलना नहीं चाहते हैं:

<input ng-model="$parent.myPrimitive">

इस इनपुट टेक्स्टबॉक्स में टाइपिंग ("22") का परिणाम नई बाल संपत्ति नहीं है। मॉडल अब माता-पिता के दायरे की संपत्ति के लिए बाध्य है (क्योंकि $ माता-पिता एक बच्चे की गुंजाइश संपत्ति है जो माता-पिता के दायरे को संदर्भित करता है)।

$ जनक के साथ एनजी-शामिल

सभी स्कोप (प्रोटोटाइप या नहीं) के लिए, कोणीय हमेशा पैरेन्ट-चाइल्ड रिलेशनशिप (यानी, एक पदानुक्रम) को ट्रैक करता है, स्कोप गुण $ पैरेंट, $$ चाइल्डहेड और $ $ चाइल्डटेल के माध्यम से। मैं आम तौर पर आरेख में इन गुंजाइश गुण नहीं दिखाते हैं।

उन परिदृश्यों के लिए जहां फ़ॉर्म तत्व शामिल नहीं हैं, एक अन्य समाधान है कि आदिम को संशोधित करने के लिए मूल कार्यक्षेत्र पर एक फ़ंक्शन को परिभाषित किया जाए। फिर सुनिश्चित करें कि बच्चा हमेशा इस फ़ंक्शन को कॉल करता है, जो कि प्रोटोटाइप विरासत के कारण बच्चे के दायरे में उपलब्ध होगा। उदाहरण के लिए,

// in the parent scope
$scope.setMyPrimitive = function(value) {
     $scope.myPrimitive = value;
}

यहां एक नमूना नमूना है जो इस "मूल फ़ंक्शन" दृष्टिकोण का उपयोग करता है। (फिडल को इस उत्तर के भाग के रूप में लिखा गया था: https://stackoverflow.com/a/14104318/215945 ।)

Https://stackoverflow.com/a/13782671/215945 और भी देखें https://github.com/angular/angular.js/issues/1267

एनजी स्विच

एनजी-स्विच गुंजाइश विरासत एनजी-शामिल की तरह काम करता है। इसलिए यदि आपको पेरेंट स्कोप में प्रिमिटिव के लिए 2-वे डेटा बाइंडिंग की आवश्यकता है, तो $ पेरेंट का उपयोग करें, या मॉडल को ऑब्जेक्ट के रूप में बदलें और फिर उस ऑब्जेक्ट की प्रॉपर्टी से बाइंड करें। इससे चाइल्ड स्कोप छिपने / पैरेंट स्कोप प्रॉपर्टीज की शैडोइंग से बच जाएगा।

यह सभी देखें AngularJS , स्विच-केस की गुंजाइश है?

एनजी-दोहराने

एनजी-रिपीट थोड़ा अलग तरीके से काम करता है। मान लें कि हमारे नियंत्रक में है:

$scope.myArrayOfPrimitives = [ 11, 22 ];
$scope.myArrayOfObjects    = [{num: 101}, {num: 202}]

और हमारे HTML में:

<ul><li ng-repeat="num in myArrayOfPrimitives">
       <input ng-model="num">
    </li>
<ul>
<ul><li ng-repeat="obj in myArrayOfObjects">
       <input ng-model="obj.num">
    </li>
<ul>

प्रत्येक आइटम / पुनरावृत्ति के लिए, एनजी-रिपीट एक नया स्कोप बनाता है, जो मूल रूप से पेरेंट स्कोप से विरासत में मिलता है, लेकिन यह नए चाइल्ड स्कोप पर एक नए प्रॉपर्टी के लिए आइटम का मान भी प्रदान करता है । (नई प्रॉपर्टी का नाम लूप वेरिएबल का नाम है।) यहाँ एनजी-रिपीट के लिए कोणीय स्रोत कोड वास्तव में क्या है:

childScope = scope.$new();  // child scope prototypically inherits from parent scope
...
childScope[valueIdent] = value;  // creates a new childScope property

यदि आइटम एक आदिम (myArrayOfPrimatics के रूप में) है, तो अनिवार्य रूप से मूल्य की एक प्रति नए बच्चे की गुंजाइश संपत्ति को सौंपी जाती है। चाइल्ड स्कोप प्रॉपर्टी की वैल्यू बदलना (यानी, एनजी-मॉडल का उपयोग करना, इसलिए चाइल्ड स्कोप num) ऐरे को पेरेंट स्कोप रेफरेंस नहीं बदलता है। इसलिए ऊपर दिए गए पहले एनजी-रिपीट में, प्रत्येक चाइल्ड स्कोप को एक ऐसी numप्रॉपर्टी मिलती है, जो myArrayOfPrimatives ऐरे से स्वतंत्र होती है:

आदिम के साथ एनजी दोहराएँ

यह एनजी-रिपीट काम नहीं करेगा (जैसे आप चाहते हैं / यह अपेक्षा करें)। टेक्स्टबॉक्स में टाइप करने से ग्रे बॉक्स में मान बदल जाते हैं, जो केवल चाइल्ड स्कोप में दिखाई देते हैं। हम जो चाहते हैं वह इनपुट के लिए है myArrayOfPrimatics सरणी को प्रभावित करने के लिए, न कि एक बाल गुंजाइश आदिम संपत्ति। इसे पूरा करने के लिए, हमें वस्तुओं की एक सरणी होने के लिए मॉडल को बदलने की आवश्यकता है।

इसलिए, यदि वस्तु एक वस्तु है, तो मूल वस्तु (प्रति नहीं) का एक संदर्भ नए बच्चे की गुंजाइश संपत्ति को सौंपा जाता है। बच्चे गुंजाइश संपत्ति के मूल्य में परिवर्तन करना (अर्थात एनजी-मॉडल का उपयोग, इसलिए obj.num) करता वस्तु माता पिता गुंजाइश संदर्भ बदल जाते हैं। तो ऊपर दूसरे एनजी-रिपीट में, हमारे पास है:

वस्तुओं के साथ दोहराना

(मैं एक लाइन ग्रे रंग से बस इतना करता हूं कि यह स्पष्ट है कि यह कहां जा रहा है।)

यह उम्मीद के मुताबिक काम करता है। टेक्स्टबॉक्स में टाइप करने से ग्रे बॉक्स में मान बदल जाते हैं, जो बच्चे और माता-पिता दोनों को दिखाई देते हैं।

यह भी देखें एनजी-मॉडल के साथ कठिनाई, एनजी-दोहराने, और आदानों और https://stackoverflow.com/a/13782671/215945 के

एनजी नियंत्रक

एनजी-नियंत्रक परिणामों का उपयोग करते हुए नेस्टिंग नियंत्रक सामान्य प्रोटोटाइप विरासत में, एनजी-शामिल और एनजी-स्विच की तरह, इसलिए एक ही तकनीक लागू होती है। हालांकि, "इसे दो नियंत्रकों के लिए $ स्कोप इनहेरिटेंस के माध्यम से जानकारी साझा करने के लिए बुरा रूप माना जाता है" - http://onehungrymind.com/angularjs-sticky-notes-pt-1-altecture/ बीच डेटा साझा करने के लिए एक सेवा का उपयोग किया जाना चाहिए इसके बजाय नियंत्रकों।

(यदि आप वास्तव में कंट्रोलर्स स्कोप इनहेरिटेंस के माध्यम से डेटा साझा करना चाहते हैं, तो आपको कुछ भी करने की आवश्यकता नहीं है। चाइल्ड स्कोप के पास सभी पेरेंट स्कोप प्रॉपर्टीज की एक्सेस होगी। लोड करते या नेविगेट करते समय कंट्रोलर लोड ऑर्डर भी अलग-अलग होते हैं। )

निर्देशों

  1. चूक (scope: false ) - निर्देश एक नया क्षेत्र नहीं बनाता है, इसलिए यहां कोई विरासत नहीं है। यह आसान है, लेकिन खतरनाक भी है, क्योंकि, एक निर्देश शायद यह सोच सकता है कि यह एक नई संपत्ति बना रहा है, जब वास्तव में यह एक मौजूदा संपत्ति को रोक रहा है। निर्देश लिखने के लिए यह एक अच्छा विकल्प नहीं है जो पुन: प्रयोज्य घटकों के रूप में अभिप्रेत है।
  2. scope: true- निर्देश एक नया चाइल्ड स्कोप बनाता है जो मूल रूप से पेरेंट स्कोप से विरासत में मिला है। यदि एक से अधिक निर्देश (एक ही DOM तत्व पर) एक नए दायरे का अनुरोध करते हैं, तो केवल एक नया चाइल्ड स्कोप बनाया जाता है। चूंकि हमारे पास "सामान्य" प्रोटोटाइप विरासत है, यह एनजी-शामिल और एनजी-स्विच की तरह है, इसलिए पेरेंट स्कोप प्रिमिटिव्स के लिए बाइंडिंग 2-वे डेटा से सावधान रहें, और पेरेंट स्कोप प्रॉपर्टीज के चाइल्ड स्कोप हाइडिंग / शैडोइंग।
  3. scope: { ... }- निर्देश एक नया पृथक / पृथक क्षेत्र बनाता है। यह प्रोटोटाइपिक रूप से विरासत में नहीं मिलता है। पुन: प्रयोज्य घटकों को बनाते समय यह आमतौर पर आपका सबसे अच्छा विकल्प होता है, क्योंकि निर्देश गलती से मूल अंश को नहीं पढ़ या संशोधित कर सकता है। हालांकि, इस तरह के निर्देशों को अक्सर कुछ मूल गुंजाइश गुणों तक पहुंच की आवश्यकता होती है। ऑब्जेक्ट हैश का उपयोग पेरेंट स्कोप और आइसोलेट स्कोप के बीच दो-तरफ़ा बाइंडिंग ('=' का उपयोग करके) या वन-वे बाइंडिंग ('@') का उपयोग करने के लिए किया जाता है। पैरेंट स्कोप एक्सप्रेशन के लिए बाध्य करने के लिए 'और' भी है। तो, ये सभी स्थानीय स्कोप गुण बनाते हैं जो मूल स्कोप से प्राप्त होते हैं। ध्यान दें कि बाइंडिंग सेट करने में मदद करने के लिए विशेषताओं का उपयोग किया जाता है - आप ऑब्जेक्ट हैश में केवल पैरेंट स्कोप प्रॉपर्टी के नाम का संदर्भ नहीं दे सकते, आपको एक विशेषता का उपयोग करना होगा। उदाहरण के लिए, यह काम नहीं करेगा यदि आप मूल संपत्ति में बाँधना चाहते हैंparentPropअलग दायरे में: <div my-directive>और scope: { localProp: '@parentProp' }। प्रत्येक माता-पिता की संपत्ति को निर्दिष्ट करने के लिए एक विशेषता का उपयोग किया जाना चाहिए जो निर्देश को बांधना चाहता है: <div my-directive the-Parent-Prop=parentProp>और scope: { localProp: '@theParentProp' }
    गुंजाइश के __proto__संदर्भ वस्तु को अलग करें । आइसोलेट स्कोप के $ पेरेंट पेरेंट स्कोप को संदर्भित करते हैं, इसलिए यद्यपि यह अलग-थलग है और पेरेंट स्कोप से प्रोटोटाइप से इनहेरिट नहीं होता है, फिर भी यह एक चाइल्ड स्कोप है।
    नीचे दी गई तस्वीर के लिए हमारे पास
    <my-directive interpolated="{{parentProp1}}" twowayBinding="parentProp2">और
    scope: { interpolatedProp: '@interpolated', twowayBindingProp: '=twowayBinding' }
    इसके अलावा, मान लीजिए कि यह निर्देशन अपने लिंकिंग फंक्शन में करता है: scope.someIsolateProp = "I'm isolated"
    अलग-अलग गुंजाइश
    अलग-अलग स्कोप की अधिक जानकारी के लिए देखें http://onehungrymind.com/angularjs-sticky-notes-pt-2-isolated-scope/
  4. transclude: true- निर्देश एक नया "ट्रांसकोडेड" चाइल्ड स्कोप बनाता है, जो मूल रूप से पेरेंट स्कोप से विरासत में मिला है। ट्रांसकोडेड और अलग-थलग स्कोप (यदि कोई हो) भाई-बहन हैं - प्रत्येक स्कोप की $ पेरेंट प्रॉपर्टी एक ही पेरेंट स्कोप का संदर्भ देती है। जब एक transcluded और एक अलग गुंजाइश दोनों मौजूद होते हैं, तो अलग-अलग गुंजाइश संपत्ति $ $ अगली अगली ट्रांसकोड किए गए दायरे को संदर्भित करेगी। मैं transcluded गुंजाइश के साथ किसी भी बारीकियों के बारे में पता नहीं कर रहा हूँ।
    नीचे दी गई तस्वीर के लिए, इस जोड़ के साथ ऊपर दिए गए निर्देश को मानें:transclude: true
    पारगमन गुंजाइश है

इस फिडेल में एक showScope()फ़ंक्शन होता है जिसका उपयोग एक अलग और ट्रांसकोड किए गए दायरे की जांच करने के लिए किया जा सकता है। टिप्पणियों में निर्देश देखें।


सारांश

स्कोप चार प्रकार के होते हैं:

  1. सामान्य प्रोटोटाइप गुंजाइश विरासत - एनजी-शामिल, एनजी-स्विच, एनजी-नियंत्रक, निर्देश के साथ scope: true
  2. एक कॉपी / असाइनमेंट के साथ सामान्य प्रोटोटाइप गुंजाइश विरासत - एनजी-रिपीट। एनजी-रिपीट का प्रत्येक पुनरावृत्ति एक नया चाइल्ड स्कोप बनाता है, और उस नए चाइल्ड स्कोप को हमेशा एक नई प्रॉपर्टी मिलती है।
  3. अलग गुंजाइश - साथ निर्देश scope: {...}। यह एक प्रोटोटाइप नहीं है, लेकिन '=', '@', और '&' माता-पिता के गुण गुणों तक पहुँचने के लिए एक तंत्र प्रदान करता है।
  4. transcluded गुंजाइश - साथ निर्देश transclude: true। यह एक सामान्य प्रोटोटाइप गुंजाइश वंशानुक्रम भी है, लेकिन यह किसी भी अलग-अलग दायरे का सहोदर भी है।

सभी स्कोप (प्रोटोटाइप या नहीं) के लिए, कोणीय हमेशा माता-पिता-बच्चे के रिश्ते (यानी, एक पदानुक्रम) को ट्रैक करता है, गुणों के माध्यम से $ पैर और $ $ चाइल्डहेड और $ $ चाइल्डटेल।

आरेखों के साथ उत्पन्न हुए थे * ".dot" फाइलें, जो गिटहब पर हैं । टिम कैसवेल का " लर्निंग जावास्क्रिप्ट विद ऑब्जेक्ट ग्राफ्स " रेखाचित्रों के लिए ग्राफविज़ का उपयोग करने की प्रेरणा थी।


48
बहुत बढ़िया लेख, एसओ उत्तर के लिए बहुत लंबा रास्ता, लेकिन वैसे भी बहुत उपयोगी है। कृपया इसे अपने ब्लॉग पर एक संपादक द्वारा आकार में कटौती करने से पहले रख दें।
इविन

43
मैंने AngularJS विकि पर एक प्रति लगाई ।
मार्क राजकोक

3
सुधार: "गुंजाइश के __proto__संदर्भ वस्तु को अलग करें ।" इसके बजाय "आइसोलेट स्कोप के __proto__संदर्भ एक स्कोप ऑब्जेक्ट " होना चाहिए । तो, आखिरी दो तस्वीरों में, नारंगी "ऑब्जेक्ट" बक्से के बजाय "स्कोप" बॉक्स होना चाहिए।
मार्क राजकोक

15
इस asnwer को कोणीयज गाइड में शामिल किया जाना चाहिए। यह कहीं अधिक विवादास्पद है ...
Marcelo De Zen

2
विकी मुझे हैरान कर देता है, पहले यह पढ़ता है: "प्रोटोटाइप चेन से सलाह ली जाती है क्योंकि ऑब्जेक्ट चाइल्डस्कोप में नहीं पाए जाते हैं।" और फिर यह पढ़ता है: "अगर हम चाइल्डस्कोप.प्रोपरेटिक्स सेट करते हैं, तो प्रोटोटाइप चेन से परामर्श नहीं किया जाता है।" दूसरा एक शर्त का मतलब है जबकि पहला नहीं है।
स्टीफन

140

मैं किसी भी तरह से मार्क के जवाब के साथ प्रतिस्पर्धा नहीं करना चाहता, लेकिन बस उस टुकड़े को उजागर करना चाहता था जिसने आखिरकार सब कुछ क्लिक किया जो जावास्क्रिप्ट विरासत और इसकी प्रोटोटाइप श्रृंखला के लिए किसी नए के रूप में था ।

केवल संपत्ति पढ़ता है प्रोटोटाइप श्रृंखला खोजता है, लिखता नहीं है। इसलिए जब आप सेट करें

myObject.prop = '123';

यह चेन नहीं दिखता है, लेकिन जब आप सेट करते हैं

myObject.myThing.prop = '123';

उस लिखित ऑपरेशन के भीतर एक सूक्ष्म रीडिंग चल रही है जो अपने प्रॉप में लिखने से पहले myThing को देखने की कोशिश करती है। तो इसीलिए बच्चे को ऑब्जेक्ट से लिखना। माता-पिता की वस्तुओं से बच्चे को मिलता है।


12
हालांकि यह एक बहुत ही सरल अवधारणा है, यह तब से बहुत स्पष्ट नहीं हो सकता है, मेरा मानना ​​है कि बहुत सारे लोग इसे याद करते हैं। अच्छे से कहा।
moljac024

3
बहुत बढ़िया टिप्पणी। मैं दूर ले जाता हूं, एक गैर वस्तु संपत्ति का संकल्प एक पढ़ने को शामिल नहीं करता है, जबकि एक वस्तु संपत्ति का संकल्प करता है।
स्टीफन

1
क्यों? संपत्ति के लिए प्रेरणा क्या है प्रोटोटाइप श्रृंखला नहीं जा रही है? यह पागल लगता है ...
जोनाथन।

1
यह बहुत अच्छा होगा यदि आप एक वास्तविक सरल उदाहरण जोड़ते हैं।
टायलिक

2
ध्यान दें कि यह बसने वालों के लिए प्रोटोटाइप श्रृंखला की खोज करता है । यदि कुछ नहीं मिला है, तो यह रिसीवर पर एक संपत्ति बनाता है।
बरगी

21

मैं जावास्क्रिप्ट के साथ प्रोटोटाइप वंशानुक्रम का एक उदाहरण जोड़ना चाहूंगा @Scott Driscoll उत्तर। हम Object.create () के साथ क्लासिकल इनहेरिटेंस पैटर्न का उपयोग कर रहे हैं जो EcmaScript 5 विनिर्देश का एक हिस्सा है।

पहले हम "पैरेंट" ऑब्जेक्ट फंक्शन बनाते हैं

function Parent(){

}

फिर "पैरेंट" ऑब्जेक्ट फ़ंक्शन के लिए एक प्रोटोटाइप जोड़ें

 Parent.prototype = {
 primitive : 1,
 object : {
    one : 1
   }
}

"चाइल्ड" ऑब्जेक्ट फ़ंक्शन बनाएँ

function Child(){

}

चाइल्ड प्रोटोटाइप असाइन करें (पेरेंट प्रोटोटाइप से चाइल्ड प्रोटोटाइप इनहेरिट करें)

Child.prototype = Object.create(Parent.prototype);

उचित "बाल" प्रोटोटाइप निर्माता असाइन करें

Child.prototype.constructor = Child;

एक बच्चे के प्रोटोटाइप के लिए "changeProps" विधि जोड़ें, जो बाल वस्तु में "आदिम" संपत्ति के मूल्य को फिर से लिख देगा और बाल और माता-पिता दोनों वस्तुओं में "ऑब्जेक्ट.ऑन" मान को बदल देगा।

Child.prototype.changeProps = function(){
    this.primitive = 2;
    this.object.one = 2;
};

माता-पिता (पिताजी) और बच्चे (पुत्र) की वस्तुओं को शुरू करें।

var dad = new Parent();
var son = new Child();

कॉल चाइल्ड (पुत्र) परिवर्तनप्रॉप्स विधि

son.changeProps();

परिणामों की जाँच करें।

मूल आदिम संपत्ति नहीं बदली

console.log(dad.primitive); /* 1 */

बाल आदिम संपत्ति बदल गई (फिर से लिखी गई)

console.log(son.primitive); /* 2 */

माता-पिता और बाल वस्तु। किसी के गुण बदल गए

console.log(dad.object.one); /* 2 */
console.log(son.object.one); /* 2 */

यहां काम करने का उदाहरण http://jsbin.com/xexurukiso/1/edit/

Object.create की अधिक जानकारी यहाँ https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.