2013-08-14 6 views
6

बिना बंद मानक वर्ग बनाम अंदर घोषित आम तौर पर मैं प्रोटोटाइप पर आधारित मानक OOP दृष्टिकोण का उपयोग और मेरी कक्षा इसवर्ग बंद

var std = function(){ 
    this.log = function(msg){ console.log("want to be private. " + msg) }; 
}; 

std.prototype = { 
    logInfo: function(msg){ 
     this.log(msg); 
    } 
}; 

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

var closureStd = (function(){ 
var std = function(){}; 
var log = function(msg){ console.log("I'm really private, youhooo!" + msg) }; 

std.prototype = { 
    logInfo: function(msg){ 
     log(msg); 
    } 
}; 

return std; 
})(); 

तो मेरे सवाल में बदल जाएगा: क्या std और closureStd और के बीच अंतर है क्या है कीमत मैं प्रोटोटाइप से निजी तरीकों कॉल करने के लिए सक्षम होने के लिए भुगतान करने की जरूरत?

+1

मददगार लिंक: यहाँ निर्माता कार्यों के प्रयोग पर

अधिक जानकारी [गोपनीयता की लागत] (http://blog.jcoglan.com/2012/01/19/the-cost-of- गोपनीयता /) और [जावास्क्रिप्ट मॉड्यूल पैटर्न] (http://briancray.com/posts/javascript-module-pattern) –

+0

दिलचस्प लेख के लिए धन्यवाद। यह मुझे कुछ अंक प्राप्त करता है, लेकिन सवाल का जवाब न दें ( – Ph0en1x

+0

क्षमा करें, ध्यान दें कि आप दूसरा लेख जोड़ते हैं। इसे पढ़ने की आवश्यकता है। – Ph0en1x

उत्तर

2

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

std कन्स्ट्रक्टर प्रत्येक आमंत्रण पर एक नई विधि बनाता है जबकि closureStd नहीं करता है। आपके द्वारा किए गए चाहिए यह

function std(){} 
std.prototype = { 
    log: function(msg){ console.log("want to be private. " + msg) }, 
    logInfo: function(msg){ this.log(msg); } 
}; 

और, बेशक (आप पहले से ही जानते हैं) closureStd में log समारोह पर बाहर से एक (निजी) चर में संग्रहीत किया जाता है, जबकि std उदाहरण पर यह सुलभ (और overwritable) है प्रत्येक उदाहरण (या उनके प्रोटोटाइप पर)। बंद होने पर यह स्कोप चेन (जो स्थिर माना जा सकता है) में एक परिवर्तनीय लुकअप है, जबकि विधि के लिए यह किसी ऑब्जेक्ट (और इसकी प्रोटोटाइप श्रृंखला) पर एक प्रॉपर्टी लुकअप है, जो गतिशील हो सकता है लेकिन आधुनिक इंजनों में समान रूप से अनुकूलित किया जा सकता है।

प्रोटोटाइप से निजी तरीकों को कॉल करने में सक्षम होने के लिए मुझे क्या कीमत चुकानी पड़ेगी?

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

1

मैंने प्रदर्शन को मापने के लिए कुछ tests भी बनाया (परिणाम कंसोल में होगा) और मुझे लगता है कि बंद करने में कक्षा डालने से कन्स्ट्रक्टर में विधियों को बेहतर तरीके से प्रदर्शित करने की तुलना में बेहतर प्रदर्शन प्रदर्शित होता है। आपके पास विरासत विकल्प भी हैं। तो अब के लिए मुझे नुकसान नहीं दिख रहे हैं और जब मुझे निजी तरीकों की आवश्यकता होगी तो हमेशा बंद होने के दौरान कक्षा का उपयोग करेंगे।

1

ध्यान दें कि link बोंडे द्वारा प्रदत्त मॉड्यूल पैटर्न निजी उदाहरण गुणों को प्रदान नहीं करता है। यह समारोह गुणों के लिए अच्छा काम करता है के रूप में निम्नलिखित कोड को दर्शाता है के बाद से समारोह प्रत्येक उदाहरण के लिए परिवर्तन नहीं होगा, लेकिन मूल्य की संपत्तियों के लिए एक छोटे से अप्रत्याशित काम करता है:

var module = (function() { 
    // private variables and functions 
    var foo = 'bar'; 
    // constructor 
    var module = function (name) { 
     // instance variables 
     this.name=name; 
    }; 
    // prototype 
    module.prototype = { 
     constructor: module, 
     something: function() { 
      // notice we're not using this.foo 
      console.log("foo in "+this.name+" is:",foo); 
      foo="new value"; 
     } 
    }; 
    // return module 
    return module; 
})(); 

var m1 = new module("m1"); 
var m2 = new module("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: new value 

आप कोड की अंतिम पंक्ति में देख सकते हैं दोनों एम 1 और m2 उदाहरण foo नामक एक निजी चर साझा करता है (सभी उदाहरण एक ही मान पर इंगित करेंगे)।

मैं other link से क्या कर सकता हूं कि बॉन्डेई ने पोस्ट किया है कि जावास्क्रिप्ट में निजीता को अनुकरण करना मुश्किल है और आप नामकरण सम्मेलन का उपयोग करने पर विचार कर सकते हैं ताकि संपत्ति निजी हो।आप Google क्लोजर कंपाइलर जैसे कुछ का उपयोग कर सकते हैं और निजी संकेतों को इंगित करने के लिए अपने जेएस कोड को एनोटेट कर सकते हैं; लेकिन क्लोजर कंपाइलर का उपयोग करने के अपने नुकसान हैं (प्रयुक्त पुस्तकालयों को संकलित नहीं किया जा सकता है जब तक कि क्लोजर कंपाइलर संगत और कोड को उन्नत मोड में संकलित करने के लिए कुछ प्रारूप में होना चाहिए)।

एक और विकल्प प्रोटोटाइप को पूरी तरह से फेंकना है (कम से कम निजी गुणों का उपयोग करके सबकुछ के लिए) और कन्स्ट्रक्टर फ़ंक्शन के शरीर में सब कुछ डालें (या किसी ऑब्जेक्ट को लौटने वाले फ़ंक्शन का उपयोग करें)।

// function returning an object 

function makeObj(name){ 
    // private vars: 
    var foo = "bar"; 
    return { 
    name:name, 
    something:function(){ 
     console.log("foo in "+this.name+" is:",foo); 
     foo="new value"; 
    } 
    } 
} 
var m1=makeObj("m1"); 
var m2=makeObj("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: bar 

// constructor with everything in the constructor's body: 

function Obj(name){ 
    // private vars: 
    var foo = "bar"; 
    this.name=name; 
    this.something=function(){ 
    console.log("foo in "+this.name+" is:",foo); 
    foo="new value"; 
    } 
} 
Obj.prototype.someOtherFunction=function(){ 
    // anything here can't access the "private" variables 
} 
var m1=new Obj("m1"); 
var m2=new Obj("m2"); 
m1.something();// foo in m1 is: bar 
m1.something();// foo in m1 is: new value 
m2.something();// foo in m2 is: bar 

एक और समस्या आप निजी उदाहरण मानों का उपयोग कर के साथ में चला सकते हैं कि वे उदाहरण में ही सुलभ हो रहा है। जब आप किसी ऑब्जेक्ट को क्लोन करना चाहते हैं और एक नया उदाहरण बनाने के लिए अपनी ऑब्जेक्ट में क्लोन फ़ंक्शन को परिभाषित करना चाहते हैं तो आपको निजी मान सेट करने के लिए सार्वजनिक एक्सेसर फ़ंक्शंस लिखना होगा क्योंकि आप उन्हें Java private fields में सीधे सेट नहीं कर सकते हैं। आप के लिए Prototypical inheritance - writing up

+0

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

+0

@silent_coder आप सही हैं, पहला उदाहरण निजी कार्यों के लिए अच्छा है, यह बोंडेई द्वारा प्रदान किए गए लिंक से कोड था। चूंकि Google पर बहुत अधिक स्कोर मैंने सोचा कि यह उल्लेख करना अच्छा है कि निजी उदाहरण मान इतना आसान नहीं हैं। – HMR