जावास्क्रिप्ट: Class.method बनाम Class.prototyp.method


498

निम्नलिखित दो घोषणाओं में क्या अंतर है?

Class.method = function () { /* code */ }
Class.prototype.method = function () { /* code using this.values */ }

क्या पहले कथन को एक स्थिर पद्धति की घोषणा के रूप में और दूसरे कथन को एक आवृत्ति विधि की घोषणा के रूप में समझना ठीक है?

जवाबों:


696

हां, पहले फ़ंक्शन का उस निर्माता फ़ंक्शन के ऑब्जेक्ट इंस्टेंस के साथ कोई संबंध नहीं है , आप इसे 'स्टैटिक विधि' की तरह मान सकते हैं ।

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

दूसरा फ़ंक्शन, जैसा कि आप कंस्ट्रक्टर फ़ंक्शन प्रोटोटाइप का विस्तार कर रहे हैं, यह newकीवर्ड के साथ बनाए गए सभी ऑब्जेक्ट इंस्टेंस के लिए उपलब्ध होगा , और उस फ़ंक्शन ( thisकीवर्ड) के भीतर संदर्भ वास्तविक ऑब्जेक्ट उदाहरण को संदर्भित करेगा जहां आप इसे कहते हैं।

इस उदाहरण पर विचार करें:

// constructor function
function MyClass () {
  var privateVariable; // private member only available within the constructor fn

  this.privilegedMethod = function () { // it can access private members
    //..
  };
}

// A 'static method', it's just like a normal function 
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};

MyClass.prototype.publicMethod = function () {
  // the 'this' keyword refers to the object instance
  // you can access only 'privileged' and 'public' members
};

var myObj = new MyClass(); // new object instance

myObj.publicMethod();
MyClass.staticMethod();

1
लेकिन Function.prototyp.method == Function.method क्यों है?
राघवेंद्र

1
@ राघवेन्द्र यह नहीं है
जोर्गेटोन

1
@ मेरा लिंक मृत है
यूजेन सोनिक

19

जब आप MyClass के एक से अधिक उदाहरण बनाते हैं, तब भी आपके पास मेमोरी में पब्लिकमैथोड का केवल एक ही उदाहरण होगा, लेकिन विशेषाधिकार प्राप्त मैथोड के मामले में आप बहुत सारे उदाहरणों का निर्माण करेंगे और staticMethod का ऑब्जेक्ट इंस्टेंस के साथ कोई संबंध नहीं है।

इसलिए प्रोटोटाइप मेमोरी को बचाते हैं।

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


15

दृश्य शिक्षार्थियों के लिए, जब फ़ंक्शन को परिभाषित किए बिना .prototype

ExampleClass = function(){};
ExampleClass.method = function(customString){
             console.log((customString !== undefined)? 
                          customString : 
                          "called from func def.");}
ExampleClass.method(); // >> output: `called from func def.`  

var someInstance = new ExampleClass();
someInstance.method('Called from instance');
    // >> error! `someInstance.method is not a function`  

एक ही कोड के साथ, यदि .prototypeजोड़ा गया है,

ExampleClass.prototype.method = function(customString){
             console.log((customString !== undefined)? 
                          customString : 
                          "called from func def.");}
ExampleClass.method();  
      // > error! `ExampleClass.method is not a function.`  

var someInstance = new ExampleClass();
someInstance.method('Called from instance');
                 // > output: `Called from instance`

इसे स्पष्ट करने के लिए,

ExampleClass = function(){};
ExampleClass.directM = function(){}  //M for method
ExampleClass.prototype.protoM = function(){}

var instanceOfExample = new ExampleClass();

ExampleClass.directM();      works
instanceOfExample.directM();   x Error!

ExampleClass.protoM();     x Error!
instanceOfExample.protoM();   works

**** ऊपर दिए गए उदाहरण के लिए नोट करें, someInstance.method () के रूप में निष्पादित नहीं किया जाएगा,
ExampleClass.method () के कारण त्रुटि और निष्पादन जारी नहीं रह सकता है।
लेकिन दृष्टांत और आसान समझ के लिए, मैंने यह क्रम बनाए रखा है। ****

से उत्पन्न परिणाम chrome developer consoleऔर कोड के माध्यम से कदम के लिए ऊपर jsbin लिंक पर क्लिक करें। + के साथ टिप्पणी अनुभाग टॉगल करेंJS Bin

ctrl/


15

हां, पहला वाला static methodभी कहा जाता है class method, जबकि दूसरा एक हैinstance method

निम्नलिखित उदाहरणों पर विचार करें, इसे और अधिक विस्तार से समझने के लिए।

ईएस 5 में

function Person(firstName, lastName) {
   this.firstName = firstName;
   this.lastName = lastName;
}

Person.isPerson = function(obj) {
   return obj.constructor === Person;
}

Person.prototype.sayHi = function() {
   return "Hi " + this.firstName;
}

उपरोक्त कोड में, isPersonएक स्थिर विधि है, जबकि sayHiएक उदाहरण विधि है Person

नीचे, Personनिर्माता से ऑब्जेक्ट बनाने का तरीका बताया गया है ।

var aminu = new Person("Aminu", "Abubakar");

स्थैतिक विधि का उपयोग करना isPerson

Person.isPerson(aminu); // will return true

उदाहरण विधि का उपयोग करना sayHi

aminu.sayHi(); // will return "Hi Aminu"

ईएस 6 में

class Person {
   constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
   }

   static isPerson(obj) {
      return obj.constructor === Person;
   }

   sayHi() {
      return `Hi ${this.firstName}`;
   }
}

देखें कि कैसे staticस्थैतिक विधि की घोषणा करने के लिए खोजशब्द का उपयोग किया गया था isPerson

Personवर्ग की वस्तु बनाना ।

const aminu = new Person("Aminu", "Abubakar");

स्थैतिक विधि का उपयोग करना isPerson

Person.isPerson(aminu); // will return true

उदाहरण विधि का उपयोग करना sayHi

aminu.sayHi(); // will return "Hi Aminu"

नोट: दोनों उदाहरण अनिवार्य रूप से समान हैं, जावास्क्रिप्ट एक वर्गहीन भाषा बनी हुई है। ईएस 6 में classपेश किया गया मुख्य रूप से मौजूदा प्रोटोटाइप-आधारित वंशानुक्रम मॉडल पर एक सिंथेटिक चीनी है।


"ES6 में" आप केवल एक वाक्यविन्यास चीनी का वर्णन करते हैं। यह "ES2015" नहीं है (कृपया सभी लोग ES6 का उपयोग करना बंद कर दें, ES2015 के उचित शब्द का उपयोग करें)। यह बस इसे करने का एक और तरीका है और मेरी राय में गलत तरीका है।
कार्ल मॉरिसन

2
@KarlMorrison अमीनू ने "ऐसा करने का तरीका" नहीं लिखा, आपने सिर्फ यह लिखा कि खुद को और इसके अपवाद को लिया। आपका मुद्दा ES6 बनाम ES2015 के बारे में उचित हो सकता है लेकिन बातचीत में लोग अक्सर दक्षता के लिए एक छोटे सम्मेलन का सहारा लेते हैं, इसलिए मुझे लगता है कि इसे लेखन से हटाना संभव नहीं है या निश्चित रूप से उचित नहीं है।
wuliwong

आपके उत्तर के ES6 भाग के लिए धन्यवाद; यह बहुत स्पष्ट करता है, खासकर जब ऊपर 2 "सार्वजनिक + विशेषाधिकारित" उत्तरों के साथ संयुक्त। मैं फिर भी कर रहा हूँ अच्छी तरह से अपने से उलझन में obj.constructor === Personकिया जा रहा है trueउदाहरण हालांकि ... Whaaaat? एक वर्ग का निर्माण करने वाला ===किस प्रकार वर्ग का स्वयं का निर्माण कर सकता है ...? (यह एक सेट का सबसेट कह रहा है जैसे खुद सेट है, आदि ...)
एंड्रयू 5

ओह्ह ... यह तो सभी को कहना है कि शाब्दिक रूप से, निर्माता एक जेएस वर्ग वास्तव में दिन के अंत में है? बाकी सब कुछ या तो कंस्ट्रक्टर में डाला जाता है या पूरी तरह से नाम / अवधारणा (और एक निहित "इस तरह" स्पष्ट रूप से उपलब्ध कराया जा रहा है) को छोड़कर वर्ग से पृथक एक स्थिर निर्माण है? (इस प्रकार, मुझे लगा कि सेट का एक सबसेट वास्तव में एक सबसेट नहीं था।)
एंड्रयू 5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.