__proto__ वी.एस. जावास्क्रिप्ट में प्रोटोटाइप


784

यह आंकड़ा फिर से दिखाता है कि प्रत्येक वस्तु का एक प्रोटोटाइप है। कंस्ट्रक्टर फंक्शन फू का भी अपना __proto__एक फंक्शन है जो __proto__फंक्शन.प्रोटोटाइप है , और जो बदले में अपनी प्रॉपर्टी के जरिए फिर से Object.prototype का भी संदर्भ देता है। इस प्रकार, दोहराएं, Foo.prototype Foo की केवल एक स्पष्ट संपत्ति है जो बी और सी वस्तुओं के प्रोटोटाइप को संदर्भित करता है।

var b = new Foo(20);
var c = new Foo(30);

__proto__और के बीच अंतर क्या हैं prototype?

यहां छवि विवरण दर्ज करें

आंकड़ा dmitrysoshnikov.com से लिया गया था ।



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

1
मुझे पसंद है कि जावास्क्रिप्ट कैसे y.constructor को y .__ proto __ के लिए हल करने के लिए प्रोटोटाइप वंशानुक्रम का उपयोग करता है। मुझे यह भी पसंद है कि कैसे Object.prototype प्रोटॉपिकल इनहेरिटेंस चेन में Object.prototype के साथ सबसे ऊपर बैठता है ।__ proto__ null पर सेट होता है। मुझे यह भी पसंद है कि आरेख एक तीन कॉलम वैचारिक दृश्य बनाता है कि प्रोग्रामर ऑब्जेक्ट्स के बारे में कैसे सोचता है 1. उदाहरण, 2. कंस्ट्रक्टर, 3. प्रोटोटाइप जो कंस्ट्रक्टर उन उदाहरणों के साथ जुड़ते हैं जब नए कीवर्ड के माध्यम से त्वरित किया जाता है।
जॉन सोंडरसन 20


और अब, जैसा कि मैंने जवाबों के माध्यम से पढ़ा है, उपरोक्त वीडियो की वास्तव में सिफारिश करने के लिए बाध्य महसूस करता हूं , क्योंकि इसमें वास्तव में एक क्रिस्टल क्लीन (और गैर-डब्ल्यूटीएफवाई) है जो :) चल रहा है, इसकी व्याख्या :)
mlvljr

जवाबों:


764

__proto__वास्तविक वस्तु है जो विधियों को हल करने के लिए लुकअप श्रृंखला में उपयोग की जाती है, आदि prototypeवह वस्तु है जिसका निर्माण __proto__तब किया जाता है जब आप किसी वस्तु के साथ बनाते हैं new:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

239
आह! तो prototypeस्वयं (या अन्य वस्तुओं) के उदाहरणों पर उपलब्ध नहीं है, लेकिन केवल निर्माण कार्यों पर।
rvighne

43
@rvighne: prototypeकार्यों पर ही उपलब्ध है, क्योंकि वे से प्राप्त कर रहे है Function, Functionऔर Objectलेकिन कुछ और में ऐसा नहीं है। हालाँकि, __proto__हर जगह उपलब्ध है।
तारिक

19
तो __proto__वास्तविक वस्तु है जिसे बचाया जाता है और प्रोटोटाइप के रूप में उपयोग किया जाता है जबकि Myconstructure.prototypeसिर्फ एक खाका __proto__होता है, जो कि बचाई गई वास्तविक वस्तु है जिसे प्रोटॉयप के रूप में सहेजा और उपयोग किया जाता है। इसलिए myobject.prototype, यह वास्तविक वस्तु की संपत्ति नहीं होगी क्योंकि इसकी सिर्फ एक अस्थायी चीज है जिसका उपयोग कंस्ट्रक्टर फ़ंक्शन द्वारा उपयोग किया myobject.__proto__जाना चाहिए।
अलेक्जाइनाबु जु

9
क्या यह कहना उचित है कि __proto__किसी वस्तु की prototypeसंपत्ति वस्तु के निर्माता के कार्य की संपत्ति का सूचक है ? अर्थात फू .__ प्रोटॉइजी === फू.कॉन्स्ट्रक्टर.प्रोटोटाइप
निको बेलिक

10
@Alex_Nabu काफी नहीं है। newCar.__proto__ आईएस Car.prototype , का उदाहरण नहीं है Car.prototype। जबकि Car.protoype आईएस एक उदाहरण है objectCar.prototypeकुछ ऐसा है जो देता है नहीं है newCarकिसी भी गुण या संरचना, यह बस है अगले objectमें newCarके प्रोटोटाइप श्रृंखला। Car.prototypeअस्थायी नहीं है object। यह वह है objectजो __proto__किसी भी नए objects के गुण का मान के रूप में सेट किया Carजाता है constructor। यदि आप किसी चीज़ को ब्लूप्रिंट के रूप में सोचना चाहते हैं object, तो Carनई कार के ब्लूप्रिंट के रूप में सोचें object
अक्टूबर को seangwright

335

prototypeएक फंक्शन ऑब्जेक्ट की एक संपत्ति है। यह उस फ़ंक्शन द्वारा निर्मित वस्तुओं का प्रोटोटाइप है।

__proto__किसी वस्तु की आंतरिक संपत्ति है, जो उसके प्रोटोटाइप की ओर इशारा करती है। वर्तमान मानक एक समान Object.getPrototypeOf(O)विधि प्रदान करते हैं , हालांकि वास्तविक मानक __proto__जल्दी होता है।

आप instanceofकिसी फ़ंक्शन की prototypeकिसी ऑब्जेक्ट की __proto__श्रृंखला से तुलना करके संबंध पा सकते हैं , और आप बदलकर इन रिश्तों को तोड़ सकते हैं prototype

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var myPoint = new Point();

// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;

यहां Pointएक निर्माण कार्य है, यह एक वस्तु (डेटा संरचना) का निर्माण करता है। myPointएक वस्तु से निर्माण किया है Point()तो Point.prototypeकरने के लिए सहेजा जाता है myPoint.__proto__उस समय।


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

। myPoint .__ आद्य __ constructor.prototype == Point.prototype
फ्रांसिस्को

@ kzh lol जिसने मुझे अजीब परिणाम दिया console.log(obj1.call) // [Function: call] obj1.call()// TypeError: obj1.call एक फ़ंक्शन नहीं है। मैंने कियाobj.__proto__ = Function.__proto__
abhisekp

myFn.__proto__ = {foo: 'bar'}
kzh

मुझे लगता है कि मुझे आपकी बात मिल गई है।
19

120

एक फ़ंक्शन घोषित होने पर प्रोटोटाइप संपत्ति बनाई जाती है।

उदाहरण के लिए:

 function Person(dob){
    this.dob = dob
 }; 

Person.prototypeप्रॉपर्टी को आंतरिक रूप से एक बार बनाया जाता है जब आप फ़ंक्शन के ऊपर घोषित करते हैं। कई गुण Person.prototype में जोड़े जा सकते हैं जो नए व्यक्ति () का उपयोग करके बनाए गए व्यक्तिगत उदाहरणों द्वारा साझा किए जाते हैं।

// adds a new method age to the Person.prototype Object.
Person.prototype.age = function(){return date-dob}; 

यह ध्यान देने योग्य है कि डिफ़ॉल्ट रूप Person.prototypeसे एक Objectशाब्दिक है (इसे आवश्यकतानुसार बदला जा सकता है)।

उपयोग किए गए हर उदाहरण new Person()में एक __proto__संपत्ति होती है जो इंगित करती है Person.prototype। यह वह श्रृंखला है जिसका उपयोग किसी विशेष वस्तु की संपत्ति खोजने के लिए किया जाता है।

var person1 = new Person(somedate);
var person2 = new Person(somedate);

के 2 उदाहरणों बनाता है Person, इन 2 वस्तुओं कॉल कर सकते हैं ageकी विधि Person.prototypeके रूप में person1.age, person2.age

अपने प्रश्न के उपरोक्त चित्र में, आप देख सकते हैं कि Fooयह एक है Function Objectऔर इसलिए इसमें एक __proto__लिंक है, Function.prototypeजिसके बदले में एक उदाहरण है Objectऔर एक __proto__लिंक है Object.prototype। प्रोटो लिंक यहाँ __proto__की Object.prototypeओर इंगित करता है null

किसी भी वस्तु की अपनी प्रोटो चेन में सभी संपत्तियों तक पहुंच हो सकती है जैसा कि इसके द्वारा जुड़ा हुआ है __proto__, इस प्रकार प्रोटोटाइप विरासत के लिए आधार बनता है।

__proto__प्रोटोटाइप श्रृंखला तक पहुंचने का एक मानक तरीका नहीं है, मानक लेकिन समान दृष्टिकोण का उपयोग करना है Object.getPrototypeOf(obj)

instanceofऑपरेटर के लिए नीचे दिया गया कोड बेहतर समझ देता है:

ऑब्जेक्ट instanceofक्लास ऑपरेटर trueतब लौटता है जब ऑब्जेक्ट क्लास का एक उदाहरण होता है, विशेष रूप से यदि Class.prototypeउस ऑब्जेक्ट की प्रोटो चेन में पाया जाता है तो ऑब्जेक्ट उस क्लास का एक उदाहरण है।

function instanceOf(Func){
  var obj = this;
  while(obj !== null){
    if(Object.getPrototypeOf(obj) === Func.prototype)
      return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}      

उपरोक्त विधि को इस प्रकार कहा जा सकता है: instanceOf.call(object, Class)यदि वस्तु कक्षा का उदाहरण है तो वापस लौटें।


2
मैं सोच रहा था कि prototypeवस्तु को पहली जगह में आंतरिक रूप से क्यों बनाया गया था ? केवल एक ही कार्य वस्तु को स्थिर तरीके प्रदान कर सकता है। जैसे function f(a){this.a = a}; f.increment = function(){return ++this.a}? इस तरीके को prototypeऑब्जेक्ट में जोड़ने के तरीके को क्यों नहीं चुना गया ? अगर f.__proto__ = gजी बेस क्लास है तो यह काम करेगा ।
abiseisekp

हो सकता है कि prototypeऑब्जेक्ट को साझा करने के लिए चुना गया था क्योंकि केवल अनन्य फ़ंक्शन कंस्ट्रक्टर गुण फ़ंक्शन कंस्ट्रक्टर ऑब्जेक्ट में संग्रहीत किए जा सकते हैं।
abhisekp

1
वास्तव में, यह एक गड़बड़ instanceofहोगी क्योंकि इसके परिणामस्वरूप संपत्ति को हटा दिए जाने पर ({}) instanceof Function === trueप्रोटोटाइप के बीच अंतर करने का कोई तरीका नहीं होगा prototype
16

@abhisekp इसका क्या मतलब है: "यह काम करेगा अगर f .__ proto__ = g जहां बेस क्लास है।" मुझे नहीं पता कि इसका कोई अर्थ है जो मुझे समझ में नहीं आता है, लेकिन यदि आप उस तरीके से गुणों और विधियों को जोड़ना चाहते थे, तो जब आपने newएक उदाहरण बनाने के लिए कीवर्ड का उपयोग किया था , तो गुणों और विधियों की प्रतिलिपि नहीं बनाई जाएगी। ऊपर।
डबलऑर्ट सेप

66

यह सोचने का एक अच्छा तरीका है ...

prototypeconstructor()कार्यों द्वारा उपयोग किया जाता है। यह वास्तव में ऐसा कुछ कहा जाना चाहिए था "prototypeToInstall", क्योंकि यह वही है।

और __proto__वह एक वस्तु पर "स्थापित प्रोटोटाइप" है (जो कहा गया constructor()फ़ंक्शन से ऑब्जेक्ट पर बनाया / स्थापित किया गया था )


2
मैंने इसे उतारा, लेकिन शायद डाउनवोट कारण था क्योंकि बयान "प्रोटोटाइप का उपयोग कंस्ट्रक्टर () फ़ंक्शंस" द्वारा किया जा सकता है, जैसे कि गैर कंस्ट्रक्टर फ़ंक्शंस में नहीं हो सकता है, जो कि मामला नहीं है, हालांकि इसके अलावा यह अब हमारा ध्यान भी नहीं है। एक नोट कर सकता है कि हर फंक्शन संभावित रूप से एक कंस्ट्रक्टर है जिसे नए के साथ कहा जाता है ...
yoel halb

2
कृपया " constructor()फ़ंक्शंस" को "कंस्ट्रक्टर फ़ंक्शंस" में बदल दें, क्योंकि " __proto__.constructor()फ़ंक्शंस" के साथ भ्रम हो सकता है । मैं इसे महत्वपूर्ण मानता हूं, जैसा कि __proto __ है। जब कोई newकीवर्ड उपयोग किया जाता है तो कंस्ट्रक्टर वास्तव में लागू नहीं होता है।
अलेक्जेंडर गोंचिए

1
यह कथन कि " प्रोटोटाइप का उपयोग कंस्ट्रक्टर () फ़ंक्शंस द्वारा किया जाता है " केवल एक महत्वपूर्ण तथ्य का एक हिस्सा बताता है, लेकिन इसे इस तरह से बताया गया है कि पाठकों को लगता है कि यह संपूर्ण तथ्य है। प्रोटोटाइप आंतरिक रूप से जावास्क्रिप्ट में प्रत्येक फ़ंक्शन घोषणा के लिए बनाया जाता है, इस बात की परवाह किए बिना कि उस फ़ंक्शन को भविष्य में कैसे कहा जाएगा - नए कीवर्ड के साथ या उसके बिना ; एक घोषित समारोह का प्रोटोटाइप एक वस्तु शाब्दिक की ओर इशारा करता है।
Yiling

62

समझाने के लिए हम एक फंक्शन बनाएं

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

जब जावास्क्रिप्ट इस कोड को निष्पादित करता है, तो यह prototypeसंपत्ति को जोड़ता है a, prototypeसंपत्ति दो गुणों वाली एक वस्तु है:

  1. constructor
  2. __proto__

तो जब हम करते हैं

a.prototype यह लौट आता है

     constructor: a  // function definition
    __proto__: Object

अब जैसा कि आप देख सकते हैं constructorकि फ़ंक्शन के अलावा कुछ भी नहीं aहै और जावास्क्रिप्ट __proto__के मूल स्तर को इंगित करता है Object

आइए देखें कि जब हम कुंजी शब्द के aसाथ फ़ंक्शन का उपयोग करते हैं तो क्या होता newहै।

var b = new a ('JavaScript');

जब जावास्क्रिप्ट इस कोड को निष्पादित करता है तो यह 4 चीजें करता है:

  1. यह एक नई वस्तु बनाता है, एक खाली वस्तु // {}
  2. यह बनाता __proto__है bऔर इसे इंगित करता a.prototypeहैb.__proto__ === a.prototype
  3. यह नवनिर्मित ऑब्जेक्ट (इसके चरण 1 में बनाया गया) के साथ अपने संदर्भ (इस) के रूप में निष्पादित a.prototype.constructor(जो फ़ंक्शन की परिभाषा है a), इसलिए nameसंपत्ति को 'जावास्क्रिप्ट' (जो जोड़ा thisजाता है ) के रूप में पारित हो जाता है, नए बनाए गए ऑब्जेक्ट में जुड़ जाता है।
  4. यह नव निर्मित वस्तु (चरण # 1 में बनाया गया) लौटाता है, इसलिए var bनव निर्मित वस्तु को सौंपा जाता है।

अब अगर हम जोड़ते हैं a.prototype.car = "BMW"और करते हैं b.car, तो आउटपुट "बीएमडब्ल्यू" दिखाई देता है।

इसका कारण यह है कि जब जावास्क्रिप्ट ने इस कोड को निष्पादित carकिया b, तो इसने संपत्ति पर खोज की , तो यह नहीं मिला कि जावास्क्रिप्ट का उपयोग किया b.__proto__गया था (जो कि चरण 2 में 'a.prototype' को इंगित करने के लिए बनाया गया था) और carसंपत्ति पाता है ताकि "बीएमडब्ल्यू" वापस मिल जाए।


2
1. constructorनहीं लौटा a()! यह लौट आता है a। 2. __proto__रिटर्न Object.prototype, जावास्क्रिप्ट में रूट ऑब्जेक्ट नहीं।
डबलऑर्ट सेप

1
यह एक महान जवाब है!
जॉन-रेमन

+1 यह समझाने के लिए सबसे अच्छा उत्तर है कि वास्तव में क्या प्रोटोटाइप है (दो गुणों वाली एक वस्तु) और कैसे जावास्क्रिप्ट कोड के प्रत्येक टुकड़े को निष्पादित करता है। यह जानकारी आश्चर्यजनक रूप से कठिन है।
java-addict301

53

प्रोटोटाइप वी.एस. __proto__ वी.एस. [[प्रोटोटाइप]]

फ़ंक्शन बनाते समय, प्रोटोटाइप नामक एक प्रॉपर्टी ऑब्जेक्ट स्वचालित रूप से बनाया जा रहा है (आपने इसे स्वयं नहीं बनाया है) और फ़ंक्शन ऑब्जेक्ट ( constructor) के साथ जोड़ा जा रहा है ।
नोट : यह नई प्रोटोटाइप ऑब्जेक्ट देशी जावास्क्रिप्ट ऑब्जेक्ट के लिए एक आंतरिक-निजी लिंक भी इंगित करता है, या है।

उदाहरण:

function Foo () {
    this.name = 'John Doe';
}

// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true

// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
    return 'My name is ' + this.name;
}

यदि आप कीवर्ड का Fooउपयोग करके कोई नया ऑब्जेक्ट बनाते newहैं, तो आप मूल रूप से (अन्य चीजों के बीच) एक नई ऑब्जेक्ट बना रहे हैं जिसमें फ़ंक्शन के आंतरिक या निजी लिंक हैं जिनकी Fooहमने पहले चर्चा की थी:

var b = new Foo();

b.[[Prototype]] === Foo.prototype  // true


निजी कि समारोह के वस्तु को लिंकेज डबल कोष्ठक प्रोटोटाइप या बस कहा जाता है [[Prototype]]। कई ब्राउज़र हमें एक सार्वजनिक लिंकेज प्रदान कर रहे हैं जो इसे कहते हैं __proto__!

अधिक विशिष्ट होने के लिए, __proto__वास्तव में एक गेटर फ़ंक्शन है जो देशी जावास्क्रिप्ट ऑब्जेक्ट से संबंधित है। यह जो कुछ भी thisबाध्यकारी है उसका आंतरिक-निजी प्रोटोटाइप लिंकेज (रिटर्न देता [[Prototype]]है b):

b.__proto__ === Foo.prototype // true

यह ध्यान देने योग्य है कि शुरू करने से ECMAScript5, आप आंतरिक निजी लिंकेज प्राप्त करने के लिए getPrototypOf विधि का उपयोग कर सकते हैं :

Object.getPrototypeOf(b) === b.__proto__ // true


नोट: यह उत्तर नई वस्तुओं या नए निर्माणकर्ताओं को बनाने की पूरी प्रक्रिया को कवर करने का इरादा नहीं रखता है, लेकिन यह समझने में मदद करने के लिए कि क्या है __proto__, prototypeऔर [[Prototype]]यह कैसे काम करता है।


2
@ वृषभ, शीर्ष लेख पर क्लिक करें, यह ECMAScript विनिर्देशों डॉक्टर की ओर जाता है। खंड 9 (साधारण और विदेशी वस्तुएं) की जाँच करें जो इसे और अधिक विवरण में बताते हैं।
लायर एलरोम

मुझे लगता है कि यहां कुछ गलती है: _ एक नई वस्तु जिसमें फ़ंक्शन के प्रोटोटाइप फू का आंतरिक या निजी लिंक है F__ क्या आपका मतलब है: एक नई वस्तु जिसका फ़ंक्शन फू के प्रोटोटाइप से आंतरिक या निजी लिंक है ?
कोरे तुगे

1
धन्यवाद @KorayTugay! हां, मैंने इसे गलत बताया :) +1
लिर एलोम

30

उपरोक्त महान उत्तरों के अतिरिक्त इसे थोड़ा स्पष्ट करने के लिए:

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

var eve = new Person("Eve");

eve.__proto__ == Person.prototype //true

eve.prototype  //undefined

उदाहरणों में __proto__ है , कक्षाओं में प्रोटोटाइप है


12

जावास्क्रिप्ट में, एक फ़ंक्शन का उपयोग एक कंस्ट्रक्टर के रूप में किया जा सकता है। इसका मतलब है कि हम नए कीवर्ड का उपयोग करके उनमें से वस्तुएँ बना सकते हैं। हर निर्माण कार्य उनके साथ जंजीर में बांधी गई वस्तु के साथ आता है। इस अंतर्निहित वस्तु को एक प्रोटोटाइप कहा जाता है।Instances of a constructor function use __proto__ to access the prototype property of its constructor function.

प्रोटोटाइप आरेख

  1. पहले हमने एक कंस्ट्रक्टर बनाया function Foo(){}:। स्पष्ट होने के लिए, फू केवल एक और कार्य है। लेकिन हम नए कीवर्ड के साथ इससे एक ऑब्जेक्ट बना सकते हैं। इसलिए हम इसे कंस्ट्रक्टर फंक्शन कहते हैं

  2. प्रत्येक फ़ंक्शन में एक अद्वितीय गुण होता है जिसे प्रोटोटाइप संपत्ति कहा जाता है। तो, कंस्ट्रक्टर फ़ंक्शन Fooमें एक प्रोटोटाइप गुण है जो इसके प्रोटोटाइप को इंगित करता है, जो कि Foo.prototype(छवि देखें) है।

  3. कंस्ट्रक्टर फ़ंक्शन स्वयं एक फ़ंक्शन है जो एक सिस्टम कंस्ट्रक्टर का उदाहरण है जिसे [[फंक्शन]] कंस्ट्रक्टर कहा जाता है। तो हम कह सकते हैं कि function Fooएक [[फंक्शन]] कंस्ट्रक्टर द्वारा बनाया गया है। तो, __proto__हमारे Foo functionअपने निर्माता के प्रोटोटाइप को इंगित करेगा, जो कि है Function.prototype

  4. Function.prototypeअपने आप में एक वस्तु के सिवा और कुछ भी नहीं है जिसे किसी अन्य सिस्टम कंस्ट्रक्टर से निर्मित किया जाता है [[Object]]। तो, [[Object]]का निर्माता है Function.prototype। इसलिए, हम कह सकते हैं कि Function.prototypeइसका एक उदाहरण है [[Object]]। तो __proto__के Function.prototypeअंक के लिए Object.prototype

  5. Object.prototypeप्रोटोटाइप श्रृंखला में खड़ा आखिरी आदमी है। मेरा मतलब है कि इसका निर्माण नहीं किया गया है। यह पहले से ही सिस्टम में है। तो इसके __proto__अंक null

  6. अब हम उदाहरण के लिए आते हैं Foo। जब हम एक उदाहरण का उपयोग करके बनाते हैं new Foo(), तो यह एक नई वस्तु बनाता है जो एक उदाहरण है Foo। इसका मतलब Fooहै कि इन उदाहरणों का निर्माता। यहां हमने दो उदाहरण (x और y) बनाए हैं। __proto__x और y इस प्रकार इंगित करता है Foo.prototype


बस स्पष्ट होने के लिए: उदाहरणों के पास कोई .prototype संपत्ति नहीं है? केवल निर्माण कार्य सही है? ... तो एक उदाहरण और इसके निर्माण कार्य के बीच एक अंतर है: निर्माण कार्यों में दोनों 1 हैं। प्रोटो 2। .प्रोटोकेशन ऑब्जेक्ट जबकि उदाहरण केवल .__ proto__ संपत्ति ... सही है?
शाज़

@ शाज आप सही हैं। उदाहरण उनके निर्माता फ़ंक्शन के प्रोटोटाइप संपत्ति तक पहुंचने के लिए उनके प्रोटो का उपयोग करते हैं।
अल-ज़मी

लेकिन ऐसा क्यों है जब आप लिखते हैं: var कार = Object.create (वाहन); आपको कार मिल जाएगी ।__ proto__ = वाहन लेकिन क्या आपको भी एक कार मिल जाएगी।
शाज़

@ शहज़ाद आप एक jsfiddle प्रदान कर सकते हैं ताकि मैं स्थिति की कल्पना कर सकूं?
अल-ज़मी

1
यहाँ car.prototype एक विरासत में मिली संपत्ति है। कार वाहन समारोह से 'प्रोटोटाइप' संपत्ति विरासत में मिली। so car.prototype === vehicle.prototype। "प्रोटोटाइप" संपत्ति वाहन पर एक संपत्ति है। कार अपनी प्रोटोटाइप श्रृंखला के माध्यम से इसे एक्सेस कर सकती है। मुझे आशा है कि इससे आपका भ्रम दूर हो जाएगा
AL-zami

8

सारांश:

__proto__ऑब्जेक्ट की संपत्ति एक ऐसी संपत्ति है जो ऑब्जेक्ट prototypeके कंस्ट्रक्टर फ़ंक्शन के लिए मैप करती है। दूसरे शब्दों में:

instance.__proto__ === constructor.prototype // true

इसका उपयोग prototypeकिसी वस्तु की श्रृंखला बनाने के लिए किया जाता है । prototypeश्रृंखला एक वस्तु पर गुणों के लिए एक देखने तंत्र है। यदि किसी ऑब्जेक्ट की संपत्ति एक्सेस की जाती है, तो जावास्क्रिप्ट पहले ऑब्जेक्ट पर ही दिखेगा। यदि संपत्ति वहाँ नहीं पाई जाती है, तो यह मिलने protochainतक सभी तरह से चढ़ाई करेगी (या नहीं)

उदाहरण:

function Person (name, city) {
  this.name = name;
}

Person.prototype.age = 25;

const willem = new Person('Willem');

console.log(willem.__proto__ === Person.prototype); // the __proto__ property on the instance refers to the prototype of the constructor

console.log(willem.age); // 25 doesn't find it at willem object but is present at prototype
console.log(willem.__proto__.age); // now we are directly accessing the prototype of the Person function 

हमारा पहला लॉग परिणाम है true, यह इसलिए है क्योंकि __proto__निर्माणकर्ता द्वारा बनाई गई उदाहरण की संपत्ति का उल्लेख निर्माणकर्ता की prototypeसंपत्ति को दर्शाता है । याद रखें, जावास्क्रिप्ट में, फ़ंक्शन भी ऑब्जेक्ट हैं। ऑब्जेक्ट्स में गुण हो सकते हैं, और किसी भी फ़ंक्शन की डिफ़ॉल्ट संपत्ति प्रोटोटाइप नाम की एक संपत्ति है।

फिर, जब इस फ़ंक्शन को एक कंस्ट्रक्टर फ़ंक्शन के रूप में उपयोग किया जाता है, तो इससे प्राप्त वस्तु को एक संपत्ति कहा जाता है __proto__। और यह __proto__संपत्ति prototypeकंस्ट्रक्टर फ़ंक्शन की संपत्ति को संदर्भित करती है (जो डिफ़ॉल्ट रूप से प्रत्येक फ़ंक्शन है)।

यह क्यों उपयोगी है?

जावास्क्रिप्ट में एक तंत्र होता है जब गुणों की तलाश Objectsहोती है, जिसे 'प्रोटोटाइप इनहेरिटेंस' कहा जाता है , यहां मूल रूप से यही किया जाता है:

  • पहले, यह जाँच की जाती है कि क्या संपत्ति ऑब्जेक्ट पर ही स्थित है। यदि हां, तो यह संपत्ति वापस आ गई है।
  • यदि संपत्ति स्वयं वस्तु पर स्थित नहीं है, तो यह 'प्रोटोकैन पर चढ़ जाएगा'। यह मूल रूप से __proto__संपत्ति द्वारा संदर्भित वस्तु को देखता है। वहां, यह जाँचता है कि क्या संपत्ति द्वारा निर्दिष्ट वस्तु पर उपलब्ध है __proto__
  • यदि प्रॉपर्टी __proto__ऑब्जेक्ट पर स्थित नहीं है , तो यह __proto__चेन, सभी तरह से Objectऑब्जेक्ट पर चढ़ जाएगा ।
  • यदि वह वस्तु और उसकी prototypeश्रृंखला पर कहीं भी संपत्ति नहीं पा सकता है , तो वह वापस आ जाएगी undefined

उदाहरण के लिए:

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

let mySelf = new Person('Willem');

console.log(mySelf.__proto__ === Person.prototype);

console.log(mySelf.__proto__.__proto__ === Object.prototype);


7

मुझे लगता है कि आप जेएस से नहीं जानते हैं कि यह प्रोटोटाइप है: यह और ऑब्जेक्ट प्रोटोटाइप , जो डिजाइन को समझने और इतनी सारी भ्रांतियों को स्पष्ट करने के लिए एक अद्भुत पुस्तक है (इसीलिए मैं विरासत और जैसी चीजों का उपयोग करने से बचने की कोशिश कर रहा हूं instanceof)।

लेकिन मेरे पास वही सवाल है जो लोग यहां पूछते हैं। कई उत्तर वास्तव में सहायक और ज्ञानवर्धक हैं। मैं अपनी समझ साझा करना पसंद करूंगा।


एक प्रोटोटाइप क्या है?

जावास्क्रिप्ट में वस्तुओं में एक आंतरिक गुण होता है, जिसे विनिर्देशन में निरूपित किया जाता है [[Prototype]], जो किसी अन्य वस्तु के लिए एक संदर्भ है। लगभग सभी वस्तुओं को nullउनके निर्माण के समय इस संपत्ति के लिए एक गैर- मूल्य दिया जाता है ।

किसी वस्तु का प्रोटोटाइप कैसे प्राप्त करें?

के माध्यम से __proto__याObject.getPrototypeOf

var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true

function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype

क्या है prototype?

prototypeकिसी ऑब्जेक्ट को किसी फ़ंक्शन की विशेष संपत्ति के रूप में स्वचालित रूप से बनाया जाता है , जिसका उपयोग प्रतिनिधिमंडल (इनहेरिटेंस) श्रृंखला, उर्फ ​​अनुकूलन श्रृंखला को स्थापित करने के लिए किया जाता है।

जब हम एक समारोह बनाने a, prototypeस्वचालित रूप से पर एक विशेष संपत्ति के रूप में बनाई गई है aऔर के रूप में पर समारोह कोड की बचत होती है constructorपर prototype

function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true

मैं इस संपत्ति को फ़ंक्शन ऑब्जेक्ट के गुणों (विधियों सहित) को संग्रहीत करने के स्थान के रूप में विचार करना पसंद करूंगा। यही कारण है कि जेएस में उपयोगिता कार्यों को परिभाषित किया जाता है Array.prototype.forEach(), जैसे Function.prototype.bind(),Object.prototype.toString().

किसी फ़ंक्शन की संपत्ति पर जोर देने के लिए क्यों ?

{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}

// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();

तो, Arary, Function, Objectसभी कार्यों कर रहे हैं। मुझे यह स्वीकार करना चाहिए कि यह जेएस पर मेरी छाप को ताज़ा करता है। मुझे पता है कि फ़ंक्शन जेएस में प्रथम श्रेणी के नागरिक हैं लेकिन ऐसा लगता है कि यह कार्यों पर बनाया गया है।

बीच क्या अंतर है __proto__और prototype?

__proto__एक संदर्भ अपनी संपत्ति को संदर्भित करने के लिए हर वस्तु पर काम करता [[Prototype]]है।

prototypeकिसी ऑब्जेक्ट को किसी फ़ंक्शन की विशेष संपत्ति के रूप में स्वचालित रूप से बनाया जाता है , जिसका उपयोग फ़ंक्शन ऑब्जेक्ट के गुणों (विधियों सहित) को संग्रहीत करने के लिए किया जाता है।

इन दोनों के साथ, हम मानसिक रूप से प्रोटोटाइप श्रृंखला का नक्शा तैयार कर सकते हैं। जैसे यह चित्र दिखाता है:

function Foo() {}
var b = new Foo();

b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true

7

 जावास्क्रिप्ट प्रोटोटाइप __prototyp__

'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true

जावास्क्रिप्ट में, प्रत्येक ऑब्जेक्ट (फ़ंक्शन ऑब्जेक्ट भी है!) के पास एक __proto__संपत्ति है, संपत्ति अपने प्रोटोटाइप का संदर्भ है।

जब हम newएक नया ऑब्जेक्ट बनाने के लिए एक कंस्ट्रक्टर के साथ ऑपरेटर का उपयोग करते हैं , तो नई ऑब्जेक्ट की __proto__संपत्ति कंस्ट्रक्टर की prototypeसंपत्ति के साथ सेट हो जाएगी , फिर कंस्ट्रक्टर को नई ऑब्जेक्ट द्वारा कॉल किया जाएगा, उस प्रक्रिया में "यह" नई ऑब्जेक्ट का एक संदर्भ होगा कंस्ट्रक्टर दायरे में, नई वस्तु को अंत में वापस करें।

कंस्ट्रक्टर का प्रोटोटाइप __proto__संपत्ति है, कंस्ट्रक्टर की prototypeसंपत्ति newऑपरेटर के साथ काम करती है।

कंस्ट्रक्टर एक फंक्शन होना चाहिए, लेकिन फंक्शन हमेशा कंस्ट्रक्टर नहीं होता भले ही उसके पास prototypeप्रॉपर्टी हो।

प्रोटोटाइप श्रृंखला वास्तव में ऑब्जेक्ट की __proto__संपत्ति है जो कि उसके प्रोटोटाइप को संदर्भित करती है, और प्रोटोटाइप के प्रोटोटाइप __proto__को संदर्भित करने के लिए प्रोटोटाइप की संपत्ति है, और इसी तरह, ऑब्जेक्ट के प्रोटोटाइप की __proto__संपत्ति को संदर्भित करने के लिए जो अशक्त है।

उदाहरण के लिए:

console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A

[[Prototype]]और __proto__संपत्ति वास्तव में एक ही बात है।

हम किसी वस्तु के प्रोटोटाइप को प्राप्त करने के लिए ऑब्जेक्ट के getPrototypOf विधि का उपयोग कर सकते हैं।

console.log(Object.getPrototypeOf(a) === a.__proto__); // true

हमारे द्वारा लिखे गए किसी भी फ़ंक्शन का उपयोग newऑपरेटर के साथ एक ऑब्जेक्ट बनाने के लिए किया जा सकता है , इसलिए उन कार्यों में से कोई भी एक कंस्ट्रक्टर हो सकता है।


6

इसे समझने का एक और अच्छा तरीका:

var foo = {}

/* 
foo.constructor is Object, so foo.constructor.prototype is actually 
Object.prototype; Object.prototype in return is what foo.__proto__ links to. 
*/
console.log(foo.constructor.prototype === foo.__proto__);
// this proves what the above comment proclaims: Both statements evaluate to true.
console.log(foo.__proto__ === Object.prototype);
console.log(foo.constructor.prototype === Object.prototype);

IE11 __proto__के समर्थन के बाद ही । ऐसे IE9 के रूप में है कि संस्करण, से पहले, आप इस्तेमाल कर सकते हैं constructorपाने के लिए __proto__


केवल इतना है कि मैं इसे दूसरे तरीके से लिखूंगा: foo .__ proto__ === foo.constructor.prototype
epeleg

6

प्रोटोटाइप

प्रोटोटाइप एक फंक्शन की एक संपत्ति है। यह नए कीवर्ड के साथ (कंस्ट्रक्टर) फ़ंक्शन का उपयोग करके ऑब्जेक्ट बनाने का खाका है।

__proto__विधियों, गुणों को हल करने के लिए लुकअप श्रृंखला में उपयोग किया जाता है। जब कोई ऑब्जेक्ट बनाया जाता है (नए कीवर्ड के साथ कंस्ट्रक्टर फ़ंक्शन का उपयोग करके), __proto__(कंस्ट्रक्टर) फ़ंक्शन के लिए सेट किया जाता है

function Robot(name) {
    this.name = name;
}
var robot = new Robot();

// the following are true   
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype

भ्रम को दूर करने के लिए यहां मेरी (काल्पनिक) व्याख्या है:

कल्पना कीजिए कि फ़ंक्शन के साथ एक काल्पनिक वर्ग (खाका / कोकी कटर) जुड़ा हुआ है। उस काल्पनिक वर्ग का उपयोग वस्तुओं को त्वरित करने के लिए किया जाता है। prototypeउस काल्पनिक वर्ग की चीज़ों को जोड़ने के लिए एक्स्टेंशन मैकेनिज़्म (C #, या स्विफ्ट एक्सटेंशन में एक्स्टेंशन मेथड) है।

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

उपरोक्त की कल्पना की जा सकती है:

// imaginary class
class Robot extends Object{

    static prototype = Robot.class  
    // Robot.prototype is the way to add things to Robot class
    // since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype

    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

} 

इसलिए,

var robot = new Robot();

robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype

अब prototypeरोबोट में विधि जोड़ना :

Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)

ऊपर रोबोट श्रेणी के विस्तार के रूप में कल्पना की जा सकती है:

// Swift way of extention
extension Robot{
    function move(x, y){    
        Robot.position.x = x; Robot.position.y = y
    }
}

जिसके परिणामस्वरूप,

// imaginary class
class Robot{

    static prototype = Robot.class // Robot.prototype way to extend Robot class
    var __proto__;

    var name = "";

    // constructor
    function Robot(name) {

        this.__proto__ = prototype;
        prototype = undefined;

        this.name = name;
    }

    // added by prototype (as like C# extension method)
    function move(x, y){ 
        Robot.position.x = x; Robot.position.y = y
    };
}

अभी भी अधिक सुसंगत नामों के लिए __proto__और प्रोटोटाइप के बारे में सोच रहा है । शायद प्रोटोटाइप और विरासत?
दिमित्री

मैं कहूंगा, prototypeऔर __proto__दोनों को बचा जाना चाहिए। हमारे पास अब क्लास है और मुझे OOP पसंद है।
हसन तारेक

समस्या यह है कि वर्ग अपेक्षाकृत नया है और यह वास्तव में सुविधाजनक नहीं है जैसे Microsoft JScript (C पर काम करते समय अच्छा है और एक त्वरित और गंदे स्क्रिप्ट इंजन की जरूरत है जो हमेशा की तरह), और nashorn जावास्क्रिप्ट (जो सभी के साथ आता है jjs के तहत नए जावा इंस्टॉलेशन और जावा को शुद्ध गतिशील वातावरण में रखने का एक अच्छा तरीका है जहां आपको लगातार चीजों को पुन: स्थापित करने की आवश्यकता नहीं है)। बात यह है कि अगर कक्षा चीनी थी, तो यह एक समस्या नहीं होगी, लेकिन यह नहीं है, यह उन चीजों की पेशकश करता है जो पुराने जेएस संस्करणों में उनके बिना असंभव हैं। जैसे "फंक्शन" का विस्तार।
दिमित्री

आखिरकार हमें समर्थन मिलेगा। मैं बैकएंड डेवलपर हूं, इसलिए मेरे पास मुद्दे नहीं हैं, मैं js में शायद ही कभी कोड करता हूं।
हसन तारेक

और स्थैतिक सदस्यों को एक तरह से विरासत में देना, जिसमें माता-पिता से नए / स्थैतिक सदस्यों को जोड़ना बच्चे द्वारा देखा जाता है (जो कि मैं JScript पर ऐसा करने के बारे में नहीं सोच सकता, जो Object.assign / __ proto __ / getPrototypeOf की पेशकश नहीं करता है, इसलिए आप जड़ वस्तु के साथ छेड़छाड़ करना है। इसे अनुकरण करने के लिए)
दिमित्री

4

अगर सरल शब्द में कहा जाए तो:

> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true

यह आपको X.prototyp के गुणों को संलग्न करने की अनुमति देता है टाइप X की ऑब्जेक्ट्स को त्वरित किया गया है, और वे अभी भी __proto__ संदर्भ के माध्यम से उन नई संपत्तियों तक पहुंच प्राप्त करेंगे जो जावास्क्रिप्ट-इंजन प्रोटोटाइप श्रृंखला को चलने के लिए उपयोग करता है।


4

प्रोटोटाइप या ऑब्जेक्ट.प्रोटोटाइप एक वस्तु शाब्दिक की एक संपत्ति है। यह ऑब्जेक्ट प्रोटोटाइप ऑब्जेक्ट का प्रतिनिधित्व करता है जिसे आप प्रोटोटाइप श्रृंखला के साथ अधिक गुण या विधियों को जोड़ने के लिए ओवरराइड कर सकते हैं।

__proto__ एक एक्सेसर प्रॉपर्टी है (प्राप्त करें और सेट करें फ़ंक्शन) जो किसी ऑब्जेक्ट के आंतरिक प्रोटोटाइप को उजागर करता है, जिसके माध्यम से इसे एक्सेस किया जाता है।

संदर्भ:

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype
  2. http://www.w3schools.com/js/js_object_prototypes.asp

  3. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto


Object.prototypeएक वस्तु शाब्दिक की संपत्ति नहीं है, जो {}.prototypeअपरिभाषित रिटर्न को प्रिंट करने की कोशिश कर रही है ; हालाँकि, इसके माध्यम से पहुँचा जा सकता है {}.__proto__, जो लौटता है Object.prototype
डबलऑर्ट सेप

3

मुझे पता है, मुझे देर हो गई है, लेकिन मुझे इसे सरल बनाने की कोशिश करें।

बता दें कि एक फंक्शन है

    function Foo(message){

         this.message = message ; 
     };

     console.log(Foo.prototype);

फू फ़ंक्शन में एक प्रोटोटाइप ऑब्जेक्ट जुड़ा होगा। इसलिए, जब भी हम जावास्क्रिप्ट में एक फ़ंक्शन बनाते हैं, तो इसमें हमेशा एक प्रोटोटाइप ऑब्जेक्ट जुड़ा होता है।

अब हम आगे बढ़ते हैं और फू का उपयोग करके दो ऑब्जेक्ट बनाते हैं।

    var a = new Foo("a");
    var b = new Foo("b");
    console.log(a.message);
    console.log(b.message);
  1. अब हमारे पास दो ऑब्जेक्ट हैं, ऑब्जेक्ट ए और ऑब्जेक्ट बी। दोनों का निर्माण कंस्ट्रक्टर फू का उपयोग करके किया गया है। ध्यान रखें कंस्ट्रक्टर यहाँ केवल एक शब्द है।
  2. ऑब्जेक्ट ए और बी दोनों में संदेश संपत्ति की एक प्रति है।
  3. ये दो ऑब्जेक्ट्स ए और बी कंस्ट्रक्टर फू के प्रोटोटाइप ऑब्जेक्ट से जुड़े हैं।
  4. ऑब्जेक्ट्स ए और बी पर, हम सभी ब्राउज़रों में प्रोटो प्रॉपर्टी का उपयोग करके फू प्रोटोटाइप का उपयोग कर सकते हैं और IE में हम Object.getPrototypOf (a) या Object.getPrototypOf (b) का उपयोग कर सकते हैं

अब, Foo.prototype, ए। प्रोटो , और बी। प्रोटो सभी एक ही वस्तु को दर्शाता है।

    b.__proto__ === Object.getPrototypeOf(a);
    a.__proto__ ===  Foo.prototype;
    a.constructor.prototype  === a.__proto__;

उपरोक्त सभी सत्य हो जाएंगे।

जैसा कि हम जानते हैं, जावास्क्रिप्ट गुणों में गतिशील रूप से जोड़ा जा सकता है। हम संपत्ति को वस्तु में जोड़ सकते हैं

    Foo.prototype.Greet = function(){

         console.log(this.message);
    }
    a.Greet();//a
    b.Greet();//b
    a.constructor.prototype.Greet();//undefined 

जैसा कि आप देख रहे हैं कि हमने Foo.prototype में Greet () विधि जोड़ी है, लेकिन यह एक और b या किसी अन्य ऑब्जेक्ट में पहुँचा जा सकता है जो फू का उपयोग करके बनाया गया है।

A.Greet () को निष्पादित करते समय, जावास्क्रिप्ट पहले गुण सूची में ऑब्जेक्ट में Greet खोजेगा। नहीं खोजने पर, यह एक के प्रोटो चेन में ऊपर जाएगा । से एक। प्रोटो और फू.प्रोटोटाइप एक ही वस्तु है, जावास्क्रिप्ट ग्रीट () पद्धति को खोजेगा और इसे निष्पादित करेगा।

मुझे उम्मीद है, अब प्रोटोटाइप और प्रोटो को थोड़ा सरल किया जाता है।


3

व्याख्यात्मक उदाहरण:

function Dog(){}
Dog.prototype.bark = "woof"

let myPuppie = new Dog()

अब, myPupppie के पास __proto__प्रॉपर्टी है जो Dog.prototype को इंगित करता है।

> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}

लेकिन myPuppie के पास एक प्रोटोटाइप संपत्ति नहीं है।

> myPuppie.prototype
>> undefined

तो, __proto__mypuppie की है संदर्भ निर्माता समारोह के .prototype संपत्ति है कि इस वस्तु का दृष्टांत इस्तेमाल किया गया था करने के लिए (और वर्तमान myPuppie वस्तु "प्रतिनिधियों के लिए" यह करने के लिए संबंध नहीं है __proto__, वस्तु), जबकि myPuppie की .prototype संपत्ति (बस अनुपस्थित है के बाद से हमने इसे सेट नहीं किया है)।

एमपीजे द्वारा यहाँ अच्छी व्याख्या: प्रोटो बनाम प्रोटोटाइप - जावास्क्रिप्ट में ऑब्जेक्ट क्रिएशन


3

मैंने अपने लिए एक छोटी सी ड्राइंग बनाई है जो निम्नलिखित कोड स्निपेट का प्रतिनिधित्व करती है:

var Cat = function() {}
var tom = new Cat()

__Proto__ और प्रोटोटाइप को समझना

मेरे पास एक शास्त्रीय OO पृष्ठभूमि है, इसलिए इस तरह से पदानुक्रम का प्रतिनिधित्व करना सहायक था। इस आरेख को पढ़ने में आपकी सहायता करने के लिए, छवि में आयतों को जावास्क्रिप्ट ऑब्जेक्ट के रूप में समझें। और हाँ, फ़ंक्शन भी ऑब्जेक्ट हैं। ;)

जावास्क्रिप्ट में वस्तुओं के गुण हैं और __proto__उनमें से सिर्फ एक है।

इस संपत्ति के पीछे का विचार पूर्वजों की वस्तु को (वंशानुक्रम) पदानुक्रम में इंगित करना है।

जावास्क्रिप्ट में जड़ वस्तु है Object.prototypeऔर अन्य सभी वस्तुएं इस एक के वंशज हैं। __proto__रूट ऑब्जेक्ट की संपत्ति है null, जो विरासत श्रृंखला के अंत का प्रतिनिधित्व करती है।

आप देखेंगे कि prototypeयह फ़ंक्शंस की संपत्ति है। Catएक फ़ंक्शन है, लेकिन यह भी Functionऔर Object(मूल) फ़ंक्शन हैं। tomकोई फ़ंक्शन नहीं है, इस प्रकार यह संपत्ति नहीं है।

इस प्रॉपर्टी के पीछे का विचार किसी ऑब्जेक्ट को इंगित करना है जो निर्माण में उपयोग किया जाएगा, अर्थात जब आप newउस फ़ंक्शन पर ऑपरेटर को कॉल करेंगे।

ध्यान दें कि प्रोटोटाइप ऑब्जेक्ट्स (पीली आयत) में एक और गुण होता है, जिसे constructorसंबंधित फ़ंक्शन ऑब्जेक्ट पर वापस इंगित किया जाता है । संक्षिप्तता कारणों के लिए यह चित्रित नहीं किया गया था।

दरअसल, जब हम tomऑब्जेक्ट बनाते हैं new Cat(), तो बनाई गई ऑब्जेक्ट में कंस्ट्रक्टर फ़ंक्शन __proto__के prototypeऑब्जेक्ट पर सेट की गई संपत्ति होगी ।

अंत में, हम इस आरेख के साथ थोड़ा खेलते हैं। निम्नलिखित कथन सत्य हैं:

  • tom.__proto__संपत्ति के रूप में एक ही वस्तु को इंगित करता है Cat.prototype

  • Cat.__proto__Function.prototypeवस्तु को इंगित करता है, जैसे Function.__proto__और Object.__proto__करना।

  • Cat.prototype.__proto__और tom.__proto__.__proto__एक ही वस्तु की ओर इशारा करते हैं और वह है Object.prototype

चीयर्स!


बहुत अच्छी तरह से समझाया!
स्टैकऑवरफ्लो यूआई

@theshinylight, tom.__proto__और सख्ती से Cat.prototypeबराबर हैं, तो, tom.__proto__ === Cat.prototype और Cat.prototype === tom.__proto__सच हैं। तो, छवि में तीर से आपका क्या मतलब है ??
aXuser264

काले तीर (यदि आप इसका उल्लेख कर रहे हैं) का कोई विशेष अर्थ नहीं है, तो वस्तु की संपत्ति के अलावा अन्य। तो वस्तु prototypeकी संपत्ति है Cat(आपके प्रश्न से)।
थेशिनाइलाइट

2

परिभाषाएं

(कोष्ठक के अंदर की संख्या () नीचे लिखे कोड के लिए एक 'लिंक' है)

prototype- एक ऐसी वस्तु जो इसमें शामिल है:
=> इस विशेष ConstructorFunction.prototype(5) के कार्य (5) जो इस निर्माण कार्य (1)
=> निर्माणकर्ता फ़ंक्शन के माध्यम से निर्मित (प्रत्येक) (4) द्वारा बनाई गई या प्रत्येक निर्माता द्वारा सुलभ हैं (1) )
=> __proto__इस विशेष वस्तु का (प्रोटोटाइप ऑब्जेक्ट)

__proto__(dandor proto?) - एक लिंक किसी विशेष ऑब्जेक्ट फ़ंक्शन (1) के माध्यम से बनाई गई किसी भी ऑब्जेक्ट (2) को बीटा करता है, और उस ऑब्जेक्ट के प्रोटोटाइप ऑब्जेक्ट के गुण (5) THAT प्रत्येक प्रत्येक ऑब्जेक्ट (2) को प्रोटोटाइप के कार्यों तक पहुंचने की अनुमति देता है और विधियाँ (4) ( __proto__डिफ़ॉल्ट रूप से जेएस में हर एक वस्तु में शामिल है)

कोड वर्गीकरण

1।

    function Person (name, age) {
        this.name = name;
        this.age = age;} 

2।

    var John = new Person(‘John’, 37);
    // John is an object

3।

    Person.prototype.getOlder = function() {
        this.age++;
    }
    // getOlder is a key that has a value of the function

4।

    John.getOlder();

5।

    Person.prototype;

1

मैं एक 4 ग्रेड स्पष्टीकरण की कोशिश करूँगा:

चीजें बहुत सरल हैं। A इस prototypeबात का उदाहरण है कि कुछ का निर्माण कैसे किया जाना चाहिए। इसलिए:

  • मैं एक हूँ functionऔर मैं अपने समान नई वस्तुओं का निर्माण करता हूँprototype

  • मैं एक हूँ objectऔर मुझे __proto__एक उदाहरण के रूप में उपयोग करके बनाया गया था

प्रमाण :

function Foo() { }

var bar = new Foo()

// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true

// bar is an instance - it does not know how to create objects
bar.prototype // => undefined

1
नहीं, न तो prototypeहै और न ही एक __proto__किसी भी समय पर एक खाका के रूप में तो किसी भी वस्तु बनाने के लिए उपयोग किया जाता है या। यह धुंधली classवाक्य रचना द्वारा पेश किया गया एक मिथक है और यह पूर्ववर्ती है। जैसा कि उत्तर-पोस्ट कहती है कि यह केवल लुकअप-चेन के prototypeलिए constructorउपयोग किया जाता है और इसके साथ उपयोग किए जाने वाले पहचान के मामले में new(जो उस ढोंग-से-उत्तम दर्जे का तंत्र का हिस्सा है जो मेरे सहित कई उपयोगकर्ताओं को भ्रमित कर रहा है)।
क्रिस्टोफ कॉलिन

पहला बिंदु "मैं एक फ़ंक्शन हूं और मैं नई वस्तुओं का निर्माण करूंगा जो मेरे प्रोटोटाइप को सौंपेंगे"
नितिन जाधव

1

आपके द्वारा बनाए गए प्रत्येक फ़ंक्शन में एक संपत्ति prototypeहोती है, और यह एक खाली वस्तु के रूप में अपना जीवन शुरू करती है। जब तक आप इस फ़ंक्शन को कंस्ट्रक्टर फ़ंक्शन के रूप में उपयोग नहीं करते हैं, जब तक कि 'नए' कीवर्ड के साथ यह संपत्ति का कोई फायदा नहीं होता है।

यह अक्सर __proto__किसी वस्तु की संपत्ति के साथ भ्रमित होता है । कुछ भ्रमित हो सकते हैं और सिवाय इसके कि prototypeकिसी वस्तु की संपत्ति उन्हें किसी वस्तु का प्रोटोकोल प्राप्त कर सकती है। लेकिन यह मामला नहीं है। किसी फ़ंक्शन कंस्ट्रक्टर से बनाई गई किसी ऑब्जेक्ट prototypeको प्राप्त करने के लिए उपयोग किया जाता है __proto__

उपरोक्त उदाहरण में:

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

var eve = new Person("Eve");

console.log(eve.__proto__ == Person.prototype) // true
// this is exactly what prototype does, made Person.prototype equal to eve.__proto__

मुझे उम्मीद है कि यह समझ में आता है।


1
prototype__proto__ऑब्जेक्ट बनाने के लिए उपयोग नहीं किया जाता है । __proto__, जब पहुँचा, केवल prototypeवस्तु के लिए एक संदर्भ प्रदान करता है ।
डबलऑर्ट सिप

1

__proto__स्थैतिक तरीकों के लिए उपयोग करने के बारे में क्या ?

function Foo(name){
  this.name = name
  Foo.__proto__.collection.push(this)
  Foo.__proto__.count++

}

Foo.__proto__.count=0
Foo.__proto__.collection=[]

var bar = new Foo('bar')
var baz = new Foo('baz')

Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined

यही कारण है कि " जावास्क्रिप्ट में __proto__वी.एस. " काprototype जवाब है ?
एंड्रियास

क्या यह अच्छा है या Foo.collection.push (यह) Foo.count ++ के बारे में क्या है
सेल्वा गणपति


1

केवल एक ही वस्तु है जिसका उपयोग प्रोटिपल चेनिंग के लिए किया जाता है। इस वस्तु का स्पष्ट रूप से एक नाम और एक मूल्य है: __proto__इसका नाम है, और prototypeइसका मूल्य है। बस इतना ही।

इसे और भी आसान बनाने के लिए, इस पोस्ट के शीर्ष पर आरेख को देखें (आरेख soshnikov द्वारा आरेख), आप कभी नहीं पाएंगे __proto__ भी prototypeइसके मूल्य के अलावा किसी और चीज़ के अंक ।

जिस्ट यह है: __proto__वह नाम है जो प्रोटोटाइप ऑब्जेक्ट का संदर्भ देता है, औरprototype वास्तविक प्रोटोटाइप ऑब्जेक्ट है।

यह कहने जैसा है:

let x = {name: 'john'};

xऑब्जेक्ट का नाम (पॉइंटर) है, और {name: 'john'}वास्तविक ऑब्जेक्ट (डेटा वैल्यू) है।

ध्यान दें: यह सिर्फ एक बड़े पैमाने पर सरलीकृत संकेत है कि वे उच्च स्तर पर कैसे संबंधित हैं।

अद्यतन: यहाँ बेहतर चित्रण के लिए एक सरल ठोस जावास्क्रिप्ट उदाहरण है:

let x = new String("testing") // Or any other javascript object you want to create

Object.getPrototypeOf(x) === x.__proto__; // true

इसका मतलब यह है कि जब Object.getPrototypeOf(x)हमें इसका वास्तविक मूल्य मिलता है x(जो इसका प्रोटोटाइप है), तो वास्तव __proto__में xयही इशारा कर रहा है। इसलिए __proto__वास्तव में के प्रोटोटाइप की ओर इशारा कर रहा है x। इस प्रकार __proto__संदर्भ x(सूचक x), और (इसके प्रोटोटाइप) prototypeका मूल्य है x

मुझे उम्मीद है कि अब यह थोड़ा स्पष्ट है।


1

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

function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]

जब हम एक फ़ंक्शन के बिना एक सामान्य वस्तु बनाते हैं, तो स्पष्ट रूप से एक फ़ंक्शन से, इसका प्रोटोटाइप नहीं होता है, लेकिन इसमें एक खाली प्रोटो होता है जिसे एक प्रोटोटाइप सौंपा जा सकता है।

var foo={
  check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); //  TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo

किसी ऑब्जेक्ट को स्पष्ट रूप से लिंक करने के लिए हम Object.create का उपयोग कर सकते हैं।

// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`

0

__proto__निर्माण के लिए आधार है prototypeऔर एक निर्माता समारोह जैसे: function human(){}है prototypeके माध्यम से साझा किया जाता है जो __proto__निर्माता समारोह का नया उदाहरण में। अधिक विस्तृत यहाँ पढ़ें


@ डरिक डैनियल: सुनिश्चित नहीं है कि आपने इसे वोट क्यों दिया लेकिन आपके द्वारा किया गया संपादन ऐसा नहीं था कि मैं व्यक्त करने की कोशिश कर रहा था। इसे और अधिक निकासी के लिए संपादित किया :)।
ज्योति दूहन

ज्योति, मैंने अपना जवाब नहीं दिया, किसी और ने किया, मैंने अभी इसे संपादित किया :)
फ्रीलांसर

0

जैसा कि यह सही कहा गया है

__proto__वह वास्तविक वस्तु है जो विधियों को हल करने के लिए लुकअप श्रृंखला में उपयोग की जाती है, आदि प्रोटोटाइप वह वस्तु है जिसका उपयोग निर्माण के लिए __proto__तब किया जाता है जब आप किसी वस्तु को नया बनाते हैं:

( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;

हम आगे ध्यान दे सकते __proto__हैं कि किसी ऑब्जेक्ट की संपत्ति फंक्शन कंस्ट्रक्टर पॉइंट्स का उपयोग करके बनाई गई मेमोरी लोकेशन से संबंधित संबंधित कंस्ट्रक्टर की प्रोटोटाइप प्रॉपर्टी की ओर इशारा करती है ।

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

निम्नलिखित उदाहरण पर विचार करें:

function Human(){
    this.speed = 25;
}

var himansh = new Human();

Human.prototype.showSpeed = function(){
    return this.speed;
}

himansh.__proto__ === Human.prototype;  //true
himansh.showSpeed();    //25

//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}

//himansh.__proto__ will still continue to point towards the same original memory location. 

himansh.__proto__ === Human.prototype;  //false
himansh.showSpeed();    //25

-1

मेरी समझ यह है: __proto__ और प्रोटोटाइप सभी प्रोटोटाइप श्रृंखला तकनीक के लिए परोसे जाते हैं। अंतर अंडरस्कोर के साथ नामित कार्यों है (जैसे __proto__) स्पष्ट रूप से आह्वान किए गए डेवलपर्स के लिए लक्ष्य नहीं है। दूसरे शब्दों में, वे सिर्फ कुछ तंत्रों जैसे वंशानुक्रम आदि के लिए हैं, वे 'बैक-एंड' हैं। लेकिन अंडरस्कोर के बिना नामित कार्यों को स्पष्ट रूप से लागू करने के लिए डिज़ाइन किया गया है, वे 'फ्रंट-एंड' हैं।


3
नामकरण सम्मेलन की तुलना में अधिक __proto__और हैं prototype। वे एक ही वस्तु को इंगित कर सकते हैं या नहीं। @Zyklus उत्तर देखें।
डेमेक्स

1
@demisx बेशक आपने सही कहा है, लेकिन मेरी राय नाम का अंतर है जो कार्यक्षमता के विपरीत है।
बेइकाई

यह केवल "आपकी समझ के अनुसार"
बताने के

-3

!!! यह दुनिया में सबसे अच्छा प्रदर्शन है !!!!!

var q = {}
var prototype = {prop: 11}

q.prop // undefined
q.__proto__ = prototype
q.prop // 11

q.__proto__ = prototypeजब हम लिखते हैं new Class, और __proto__प्रोपर सेट में फंक्शन कंस्ट्रक्टर्स जावास्क्रिप्ट इंजन इसे अपने आप कहते हैंClass.prototype

function Class(){}
Class.prototype = {prop: 999} // set prototype as we need, before call new

var q = new Class() // q.__proto__ = Class.prototype
q.prop // 999

का आनंद लें %)

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