जावास्क्रिप्ट: .extend और .prototype क्या हैं?


122

मैं जावास्क्रिप्ट में अपेक्षाकृत नया हूं और तृतीय पक्ष के पुस्तकालयों में .extend और .prototype का उपयोग कर रहा हूं। मैंने सोचा कि इसका प्रोटोटाइप प्रोटोटाइप लाइब्रेरी के साथ क्या करना है, लेकिन मुझे लगता है कि ऐसा नहीं है। ये किस लिए उपयोग किए जाते हैं?

जवाबों:


136

जावास्क्रिप्ट की विरासत प्रोटोटाइप आधारित है, इसलिए आप दिनांक, गणित और यहां तक ​​कि अपने कस्टम कस्टम जैसे ऑब्जेक्ट के प्रोटोटाइप का विस्तार करते हैं।

Date.prototype.lol = function() {
 alert('hi');
};

( new Date ).lol() // alert message

ऊपर स्निपेट में, मैं सभी दिनांक ऑब्जेक्ट्स (पहले से मौजूद लोगों और सभी नए वाले) के लिए एक विधि निर्धारित करता हूं ।

extend आमतौर पर एक उच्च स्तरीय फ़ंक्शन होता है जो एक नए उपवर्ग के प्रोटोटाइप को कॉपी करता है जिसे आप बेस क्लास से विस्तारित करना चाहते हैं।

तो आप कुछ ऐसा कर सकते हैं:

extend( Fighter, Human )

और Fighterनिर्माता / वस्तु के प्रोटोटाइप प्राप्त कर लेंगे Human, इसलिए यदि आप इस तरह के रूप पद्धतियां निर्धारित liveऔर dieपर Humanतो Fighterउन लोगों को भी प्राप्त कर लेगा।

अद्यतित स्पष्टीकरण:

"उच्च स्तरीय फ़ंक्शन" का अर्थ .extend अंतर्निहित नहीं है, लेकिन अक्सर एक पुस्तकालय द्वारा प्रदान किया जाता है जैसे कि jQuery या प्रोटोटाइप।


75
"उच्च स्तरीय फ़ंक्शन" का अर्थ .extendअंतर्निहित नहीं है, लेकिन अक्सर एक पुस्तकालय द्वारा प्रदान किया जाता है जैसे कि jQuery या प्रोटोटाइप।
visum

13
मैं जोड़ना होगा यह जे एस में देशी वस्तुओं के प्रोटोटाइप का विस्तार करने का सुझाव दिया है नहीं कर रहा है
framp

1
@meder - आपको अपने उत्तर में विज़ुम टिप्पणी जोड़ना चाहिए। :)
मनीष गुप्ता

9
आधुनिक जावास्क्रिप्ट प्रोग्रामिंग में, यह एक सार्वजनिक बाथरूम के तत्वों की तरह गोलाकार और देशी वस्तुओं के इलाज के लिए प्रथागत है; आप वहां जाने से बच नहीं सकते, लेकिन आपको सतहों के साथ संपर्क को कम करने की कोशिश करनी चाहिए। इसका कारण यह है कि changing the native objects can break other developer's assumptions of these objects,जावास्क्रिप्ट कीड़े के लिए अग्रणी है जो अक्सर नीचे ट्रैकिंग के लिए कई घंटे खर्च कर सकते हैं। इस उत्तर पर प्रमुख वाक्य इस बहुमूल्य जावास्क्रिप्ट अभ्यास को गलत ढंग से प्रस्तुत करता है।
Ninjaxor

24

.extend()कई तृतीय-पक्ष पुस्तकालयों द्वारा जोड़ा जाता है ताकि अन्य वस्तुओं से वस्तुओं को बनाना आसान हो सके। कुछ उदाहरणों के लिए http://api.jquery.com/jQuery.extend/ या http://www.prototypjs.org/api/object/extend देखें ।

.prototype किसी ऑब्जेक्ट के "टेम्पलेट" (यदि आप इसे कॉल करना चाहते हैं) को संदर्भित करता है, इसलिए किसी ऑब्जेक्ट के प्रोटोटाइप के तरीकों को जोड़कर (आप स्ट्रिंग, दिनांक, गणित, या यहां तक ​​कि फ़ंक्शन में जोड़ने के लिए पुस्तकालयों में यह बहुत देखते हैं) उस वस्तु के हर नए उदाहरण में जोड़े जाते हैं।


19

extendउदाहरण के लिए विधि jQuery या PrototypeJS , प्रतियां गंतव्य वस्तु के लिए स्रोत से सभी गुण।

अब prototypeसंपत्ति के बारे में , यह फ़ंक्शन ऑब्जेक्ट का सदस्य है, यह भाषा कोर का हिस्सा है।

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

जब आप newकिसी फ़ंक्शन ऑब्जेक्ट पर ऑपरेटर का उपयोग करते हैं , तो एक नया ऑब्जेक्ट बनाया जाएगा, और यह उसके निर्माता से विरासत में मिलेगाprototype

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

function Foo () {
}
Foo.prototype.bar = true;

var foo = new Foo();

foo.bar; // true
foo instanceof Foo; // true
Foo.prototype.isPrototypeOf(foo); // true

18

जावास्क्रिप्ट विरासत को हर जगह एक खुली बहस की तरह लगता है। इसे "जावास्क्रिप्ट भाषा का उत्सुक मामला" कहा जा सकता है।

विचार यह है कि एक आधार वर्ग है और फिर आप वंशानुक्रम जैसी सुविधा प्राप्त करने के लिए आधार वर्ग का विस्तार करते हैं (पूरी तरह से, लेकिन अभी भी नहीं)।

संपूर्ण विचार यह है कि वास्तव में प्रोटोटाइप का मतलब क्या है। जब तक मैंने जॉन रेजिग का कोड नहीं देखा (तब तक जो jQuery.extendकरता है) के पास एक कोड चंक लिखा था, जो मुझे मिला और उसने दावा किया कि वह बेस 2 और प्रोटोटाइप लाइब्रेरी प्रेरणा का स्रोत था।

यहाँ कोड है।

    /* Simple JavaScript Inheritance
     * By John Resig http://ejohn.org/
     * MIT Licensed.
     */  
     // Inspired by base2 and Prototype
    (function(){
  var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

  // The base Class implementation (does nothing)
  this.Class = function(){};

  // Create a new Class that inherits from this class
  Class.extend = function(prop) {
    var _super = this.prototype;

    // Instantiate a base class (but only create the instance,
    // don't run the init constructor)
    initializing = true;
    var prototype = new this();
    initializing = false;

    // Copy the properties over onto the new prototype
    for (var name in prop) {
      // Check if we're overwriting an existing function
      prototype[name] = typeof prop[name] == "function" &&
        typeof _super[name] == "function" && fnTest.test(prop[name]) ?
        (function(name, fn){
          return function() {
            var tmp = this._super;

            // Add a new ._super() method that is the same method
            // but on the super-class
            this._super = _super[name];

            // The method only need to be bound temporarily, so we
            // remove it when we're done executing
            var ret = fn.apply(this, arguments);        
            this._super = tmp;

            return ret;
          };
        })(name, prop[name]) :
        prop[name];
    }

    // The dummy class constructor
    function Class() {
      // All construction is actually done in the init method
      if ( !initializing && this.init )
        this.init.apply(this, arguments);
    }

    // Populate our constructed prototype object
    Class.prototype = prototype;

    // Enforce the constructor to be what we expect
    Class.prototype.constructor = Class;

    // And make this class extendable
    Class.extend = arguments.callee;

    return Class;
  };
})();

तीन भाग हैं जो काम कर रहे हैं। सबसे पहले, आप गुणों के माध्यम से लूप करते हैं और उन्हें उदाहरण में जोड़ते हैं। उसके बाद, आप बाद में ऑब्जेक्ट में जोड़े जाने के लिए एक कंस्ट्रक्टर बनाते हैं। अब, प्रमुख लाइनें हैं:

// Populate our constructed prototype object
Class.prototype = prototype;

// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;

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

और उपयोग उदाहरण:

var Car = Class.Extend({
  setColor: function(clr){
    color = clr;
  }
});

var volvo = Car.Extend({
   getColor: function () {
      return color;
   }
});

जॉन रेजिग के पोस्ट द्वारा जावास्क्रिप्ट इनहेरिटेंस पर यहाँ इसके बारे में और पढ़ें ।


2

extendतीसरे पक्ष के पुस्तकालयों में कुछ कार्य दूसरों की तुलना में अधिक जटिल हैं। उदाहरण के लिए Knockout.js में न्यूनतम सरल एक होता है जिसमें कुछ चेक नहीं होते हैं जो jQuery के होते हैं:

function extend(target, source) {
    if (source) {
        for(var prop in source) {
            if(source.hasOwnProperty(prop)) {
                target[prop] = source[prop];
            }
        }
    }
    return target;
}

2
  • .extends() एक वर्ग बनाएं जो दूसरे वर्ग का बच्चा हो।
    पर्दे के पीछे Child.prototype.__proto__इसके मूल्य निर्धारित Parent.prototype
    किए जाते हैं ताकि तरीके विरासत में मिले।
  • .prototype एक से दूसरे में विरासत की विशेषताएं।
  • .__proto__ प्रोटोटाइप के लिए एक गेट्टर / सेटर है।

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