2010-02-05 27 views

उत्तर

2

जावास्क्रिप्ट जावा, सी ++ या इसी तरह की तरह कक्षाओं का उपयोग नहीं करता है।

अपने प्रभाव को प्राप्त करने का एक तरीका यह है कि इस कीवर्ड का उपयोग किया जाता है - सदस्यों को लगभग उतना ही एक्सेस करना जितना आप जावा में करेंगे। फिर, इस कार्य को ऑब्जेक्ट बनाने के लिए कॉल करने में नया कीवर्ड का उपयोग करें।

function Foo(){ //vaguely like a Java constructor 
    this.aField = 1; //define members simply by using 'this' 
    this.aMethod = methodFunction; //assign a function as a member using 'this' 
} 

function methodFunction(){ 
} 

var foo = new Foo(); //construct an object 
+0

विधि असाइनमेंट को ठीक किया गया; आशा है कि आपको बुरा लगेगा ... – Christoph

+1

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

+0

@ जस्टिन: कन्स्ट्रक्टर के बाहर 'विधि फ़ंक्शन() 'को परिभाषित करना सबसे निश्चित रूप से एक वास्तविक उद्देश्य प्रदान करता है: अन्यथा, प्रत्येक उदाहरण के लिए एक नया फ़ंक्शन ऑब्जेक्ट बनाया जाना चाहिए (यानी' एफ 'की संख्या में' ओ (एन) 'ओवरहेड वस्तुओं); आम तौर पर, मैं 'f.prototype' विधि को असाइन करता हूं, लेकिन ऐसा करने से विधि लुकअप – Christoph

4

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

Prototypal Inheritance in JavaScript

Classical Inheritance in JavaScript

10
// I like this pattern.. 

// class 
function Person(name, birthdate) { 
    this._name = name; 
    this._birthdate = birthdate; 
    /* should not do this 
    * this.getAge = function() { 
    * } 
    * as the method will be constructed 
    * for each instance, better to let it 
    * be inherited from prototype, see below 
    */ 
} 

// class methods 
Person.prototype.getBirthdate = function() { 
    return this._birthdate; 
} 

// same as above, function as a method 
Person.prototype.getAge = function() { 
    var currentDate = new Date(); 
    // age in millis 
    return currentDate - this._birthdate; 
} 

// the get age method can be a "static" 
// method on the constructor function if you pass the 
// person object 
Person.getAge = function(person) { 
    var currentDate = new Date(); 
    // age in millis 
    //no reference to this 
    return currentDate - person.getBirthdate(); 
} 

// you could use it like this 

myPerson = new Person("Steve", new Date("1980-01-01")); 
// returns age in millis 
myPerson.getAge(); 
// returns age in millis 
Person.getAge(myPerson); 

तुम भी एक गुमनाम समारोह का उपयोग अनुकरण करने के लिए कर सकता है निजी और सार्वजनिक

var PersonFactory = (function() { 
    // private area, no one can alter 
    // the person cache 
    var _cache = {} 

    // public area 
    return { 
    // returns a person born now 
    getPerson: function(name) { 
     if(_cache[name]) { 
     return _cache[name]; 
     } 
     else { 
     _cache[name] = new Person(name, new Date()); 
     return _cache[name]; 
     } 
    } 
    } 
})(); 

var p = PersonFactory.getPerson("Leif"); 
p.getAge(); 
p = PersonFactory.getPerson("Leif"); 
// should be the same age/obj 
p.getAge(); 

मैं इस पैटर्न पसंद नहीं है हालांकि। अंडरस्कोर चेतावनी _myVariable उन चर/विधियों का उपयोग करने से आपके lib के उपयोगकर्ताओं को रखने के लिए पर्याप्त होना चाहिए। जब मैंने पहली बार जावा जावा पृष्ठभूमि की वजह से इसे खोज लिया तो मैंने इसे आवंटित किया .. यह प्रोटोटाइप विरासत के साथ काम करना मुश्किल बनाता है और मेमोरी लीक का कारण बन सकता है।

+0

जैसा कि आप वर्णन करते हैं, कैश का उपयोग करके स्वचालित कचरा संग्रह को भी हरा देता है क्योंकि प्रोग्रामर को अब अनियंत्रित संसाधनों को मैन्युअल रूप से हटाना सुनिश्चित करना है – Christoph

+0

धन्यवाद, संपादित किया गया। – oyvindn

22

"आधुनिक" जावास्क्रिप्ट में, वस्तुओं को परिभाषित करने के लिए तीन लोकप्रिय विधियां हैं।

पहली विधि क्लासिक विधि है और इसकी सादगी के कारण अभी भी लोकप्रिय है; हालांकि, यह दूसरी विधि के पक्ष में discouraged by MDC है क्योंकि ऑब्जेक्ट का एक उदाहरण हर बार प्रत्येक फ़ंक्शन को फिर से परिभाषित करने की अक्षमता की वजह से होता है।

// Constructor, methods and members all rolled up into one definition 
var Movie = function(name) { 
    this.name = name; 
    // Note that private members can be created using the closure property 
    var _id = +(new Date()); 

    this.getName = function() { 
     return this.name + " " + _id; 
    }; 

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

var m = new Movie("Beerfest"); 

दूसरी विधि की एक विविधता है और पहले के लिए भी इस्तेमाल किया जा सकता। यह prototype संपत्ति के माध्यम से मौजूदा वस्तुओं में नई विधियों को जोड़ने के लिए भी उपयोगी है। इस फ़ॉर्म में निजी सदस्य और तरीके संभव नहीं हैं।

// Constructor is separate from its methods 
var Movie = function(name) { 
    this.name = name; 
} 

Movie.prototype.getName = function() { 
    return name; 
}; 

Movie.prototype.setName = function(name) { 
    this.name = name; 
}; 

var m = new Movie("Kill Bill"); 

तीसरे विधि है जो यह संभव new ऑपरेटर का उपयोग किए बिना वस्तुओं का दृष्टांत के लिए बनाता है module pattern उपयोग करने के लिए, है।

var Movie = function (name) { 
    var _id = +(new Date()); 
    var privateMethod = function() { alert(_id); }; 

    // All methods and members defined here are public 
    return { 
     name: name, 
     getName: function() { 
      return this.name + " " + _id; 
     }, 
     setName: function(name) { 
      this.name = name; 
     } 
    }; 
}; 

var m = Movie("Stackoverflow: the movie"); 

ध्यान दें कि पहले और तीसरे तरीकों में, आप निजी एक्सेस सदस्यों और विधियों का उपयोग कर सकते हैं। लेकिन ध्यान रखें कि to use this within private methods some must happen

0

अज्ञात स्व-निष्पादन फ़ंक्शन का उपयोग करके, आप सार्वजनिक और निजी विशेषताओं/विधियों के लिए अनुमति दे सकते हैं।

(function ($, MyObject, undefined) { 

    MyObject.publicFunction = function() { 
     console.log("Public function"); 
    }; 

    var privateFunction = function() { 
     console.log("Private function"); 
    };  

    var privateNumber = 0; 
    MyObject.sayStuff = function() { 
     this.publicFunction(); 
     privateFunction(); 
     privateNumber++; 
     console.log(privateNumber); 
    }; 


    // You can even nest the namespaces 
    MyObject.nestedNamespace = MyObject.nestedNamespace || {}; 
    MyObject.nestedNamespace.logNestedMessage = function() { 
     console.log("Nested namespace function"); 
    }; 

}(jQuery, window.MyObject = window.MyObject || {})); 

MyObject.sayStuff(); 
MyObject.sayStuff(); 
MyObject.nestedNamespace.logNestedMessage(); 
MyObject.publicFunction(); 

टिप्पणी here और this article से इसके बारे में सीखा:

यह पैटर्न मुझे सबसे ज्यादा पसंद है।

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