2010-12-15 17 views
17

सी #/PHP से आ रहा है, मैं कक्षाओं (कार्यों) पर पूर्ण गेटर्स/सेटर्स रखना चाहता हूं जो मैं जावास्क्रिप्ट के साथ बनाता हूं।जावास्क्रिप्ट में क्लास गेटर/सेटर्स बनाने का सबसे अच्छा तरीका?

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

मुझे गेटर्स और सेटर्स पर John Resig's article खोजने में प्रसन्नता हुई, लेकिन कुछ टिप्पणियां जो बताती हैं कि कुछ ब्राउज़र "गेटर्स और सेटर्स का समर्थन नहीं करते हैं" जो मुझे भ्रमित कर रहे हैं क्योंकि वे जावास्क्रिप्ट की "विशेषता" नहीं हैं लेकिन अधिक एक साधारण पैटर्न का जो मूल जावास्क्रिप्ट वाक्यविन्यास का उपयोग करता है। यह लेख 2007 में भी लिखा गया था, इसलिए अब तक इसे पुराना हो सकता है।

जावास्क्रिप्ट में गेटर्स और सेटर्स की वर्तमान स्थिति क्या है? क्या वे वास्तव में आज सभी ब्राउज़रों द्वारा "समर्थित" हैं (जो भी इसका मतलब है)? क्या वे जावास्क्रिप्ट के लिए एक उपयोगी प्रोग्रामिंग पैटर्न हैं या सार्वजनिक चर के साथ जावास्क्रिप्ट कक्षाएं (कार्य होने) बेहतर हैं? क्या निम्नलिखित से उन्हें लागू करने का कोई बेहतर तरीका है?

$(document).ready(function() { 
    var module = new Module('idcode'); 
    module.set_id_code('new idcode'); 
    module.set_title('new title'); 
    $('body').html(module.get_id_code()+': '+module.get_title()); 
}); 

function Module(id_code, title) { 
    var id_code = id_code; 
    var title = title; 

    //id_code 
    this.get_id_code = function() { 
     return id_code; 
    } 
    this.set_id_code = function(value) { 
     id_code = value; 
    } 

    //title 
    this.get_title = function() { 
     return title; 
    } 
    this.set_title = function(value) { 
     title = value; 
    } 
} 
+2

आप कोड ब्लोट क्यों चाहते हैं? – gdj

+0

बिल्कुल, मुझे कोड ब्लोट नहीं चाहिए, लेकिन मैं अपनी कक्षाओं में सार्वजनिक और निजी पहुंच को अलग करना चाहता हूं क्योंकि मैं PHP और C# जैसी अन्य भाषाओं में करता हूं। PHP में __get और __set जादू विधियां हैं और सी # में ब्लूटेड वाक्यविन्यास के बिना अलगाव प्राप्त करने के लिए "संपत्ति सिंटैक्स" है। जावास्क्रिप्ट में इस तरह की कोई विशेषताएं? –

+0

क्या आईई 7/8/9 में कोड का उपरोक्त टुकड़ा काम करता है ?? – Shaggy

उत्तर

1

getters और setters सुविधाओं, लेकिन "डिजाइन पैटर्न" भाषाओं कि संपत्ति वाक्य रचना का समर्थन नहीं करते के लिए (इस मामले में कोड ब्लोट) नहीं हैं।

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

मेरी पसंदीदा उद्धरण में से एक अजगर के समुदाय से आता है:

हम यहाँ सभी की सहमति देने वयस्कों

जब चर्चा करने के निजी चर और जानकारी छुपा जरूरत नहीं है।

उद्धरण here पाया जा सकता है।

जानें कि भाषा आपको क्या प्रदान करती है और इसकी संस्कृति और नियमों को गले लगाती है।

+1

-1 संपत्ति उत्परिवर्तन उचित encapsulation के लिए आवश्यक हैं। ऑब्जेक्ट्स को किसी अन्य ऑब्जेक्ट के इंटर्नल्स में अनुमति देना भयानक बग का कारण बनता है! इसका आंतरिक राज्य सुसंगत रखने का कोई तरीका नहीं होगा। साथ ही, भाषा मूल रूप से गेटर्स और सेटर्स का समर्थन करती है। –

5

कैसे के बारे में: यहाँ

function Module(id_code, title) { 
    var id_code = id_code; 
    var title = title; 

    var privateProps = {}; 

    this.setProperty = function(name, value) { 
     // here you could e.g. log something 
     privateProps[name] = value; 
    } 

    this.getProperty = function(name) { 
     return privateProps[name]; 
    } 
} 

मनुष्य और सेटर तरीके के लिए एक निजी गुण है कि किसी भी अन्य तरीकों से पहुँचा नहीं जा सकता स्टोर करने के लिए इस्तेमाल किया वस्तु पर काम करते हैं। तो, उदाहरण के लिए, आप एक सेटर (या गेटर) को लागू कर सकते हैं जो लॉग इन करता है या AJAX या जो कुछ भी करता है, जब भी कोई संपत्ति संशोधित होती है (गेटर/सेटर विधियों के उद्देश्यों में से एक)।

+2

यह कोई उपयोगी कार्यक्षमता प्रदान नहीं करता है। setProperty और getProperty सार्वजनिक कार्य हैं, इसलिए यह केवल एक स्तर का संकेत जोड़ता है। यह निजी गेटर और सेटर कार्यों को कॉल करने की क्षमता नहीं जोड़ता है। –

+0

यह उन गुणों को जोड़ता है जिन्हें गेटटर और सेटर विधियों के अलावा एक्सेस नहीं किया जा सकता है - ठीक उसी तरह सार्वजनिक गेटर और सेटर विधियों का उपयोग अन्य भाषाओं में निजी सदस्यों को संशोधित करने के लिए किया जाता है। यह एक प्रदर्शन है - ये विधियां अन्य चीजें भी कर सकती हैं। – sje397

+0

पर्याप्त मेला - लेकिन या तो ऐसा करने के लिए अपने कोड में एक हुक जोड़ें, या अपने कोड में एक टिप्पणी जोड़ें जहां व्यवहार को संशोधित किया जा सकता है। हां यह अनुभवी जावास्क्रिप्ट प्रोग्रामर के लिए स्पष्ट है, लेकिन शुरुआती लोगों के लिए नहीं। –

9

मुझे लगता है कि आप बिंदु खो रहे हैं, मुझे लगता है। (या शायद अन्य answerers बात को अनदेखा कर रहे हैं।) ECMAScript एक "परदे के पीछे" गेटर/सेटर तंत्र प्रदान करता है, ताकि

x.foo = 3; 
y = x.foo; 

वास्तव में (तरह) में तब्दील हो

x.PutValue("foo",3); 
y = x.GetValue("foo"); 

जहां PutValue और GetValue अज्ञात हैं, सेटर्स और गुणों के लिए गेटर्स के लिए सीधे पहुंच योग्य कार्य नहीं हैं। (ECMAScript standard, 3rd ed., सेक्शन 8.7.1 और 8.7.2 देखें) तीसरा संस्करण स्पष्ट रूप से परिभाषित नहीं करता है कि उपयोगकर्ता कस्टम गेटर्स और सेटर फ़ंक्शन कैसे सेट कर सकते हैं। मोज़िला के जावास्क्रिप्ट के कार्यान्वयन ने किया और अभी भी करता है, उदा।(इस JSDB जो जावास्क्रिप्ट 1.8 का उपयोग करता है):

js>x = {counter: 0}; 
[object Object] 
js>x.__defineGetter__("foo", function() {return this.counter++; }); 
js>x.foo 
0 
js>x.foo 
1 
js>x.foo 
2 
js>x.foo 
3 
js>x.foo 
4 

वाक्य रचना है (या कम से कम अब तक किया गया है) ब्राउज़र-विशिष्ट। विशेष रूप से इंटरनेट एक्सप्लोरर की कमी है, कम से कम this SO question के अनुसार।

ईसीएमएस्क्रिप्ट मानक का 5 वां संस्करण इस तंत्र पर मानकीकृत प्रतीत होता है। this SO question on getters and setters देखें।


संपादित: एक और अधिक व्यावहारिक उदाहरण, शायद, अपने उद्देश्यों के लिए:

function makePrivateObject() 
{ 
    var state = 0; 
    var out = {}; 
    out.__defineSetter__("foo", function(x) {}); 
    // prevent foo from being assigned directly 
    out.__defineGetter__("foo", function() { return state; }); 
    out.count = function() { return state++; } 
    return out; 
} 

js>x = makePrivateObject() 
[object Object] 
js>x.foo 
0 
js>x.foo = 33 
33 
js>x.foo 
0 
js>x.count() 
0 
js>x.count() 
1 
js>x.count() 
2 
js>x.foo 
3 
+2

यह हो सकता है कि वे आंतरिक रूप से कैसे संभाले जाते हैं लेकिन तकनीकी रूप से वे अभी भी "सार्वजनिक चर" हैं यदि मैं उन तक पहुंच नियंत्रित नहीं कर सकता। मेरे लिए गेटर्स और सेटर्स का लाभ यह है कि मैं निर्धारित कर सकता हूं उदा। कि "वेतन" संपत्ति केवल आंतरिक रूप से बदला जा सकता है, या उदा। जब यह बदल जाता है, (ए) परिवर्तन लॉग होता है, (बी) और घटना निकाल दी जाती है, आदि। जब तक मेरे पास गेटर/सेटर एक्सेसर विधियां नहीं हैं, मेरे पास मेरी कक्षाओं के लिए कार्यक्षमता की इस परत को परिभाषित करने की क्षमता नहीं है। –

+2

आह - लेकिन यहां एक सूक्ष्मता है; यदि आपके पास कस्टम गेटर/सेटर विधियों का उपयोग करने की क्षमता है, तो आप करते हैं। मैं अपना जवाब संपादित करूंगा। –

14

फायरफॉक्स, सफारी, क्रोम और ओपेरा (लेकिन आईई) सभी एक ही अमानक getter और setter तंत्र में निर्मित। ईसीएमएस्क्रिप्ट 5 में एक अलग वाक्यविन्यास शामिल है जो currently making its way into browsers है और भविष्य में मानक बन जाएगा। आईई 8 में पहले से ही यह सुविधा है, लेकिन केवल डोम नोड्स पर, नियमित देशी जावास्क्रिप्ट ऑब्जेक्ट्स नहीं।

var obj = {}; 

Object.defineProperty(obj, "value", { 
    get: function() { 
     return this.val; 
    }, 
    set: function(val) { 
     this.val = val; 
    } 
}); 
5

आप वास्तव में जावास्क्रिप्ट में setters और getters को परिभाषित करने और सिर्फ उन्हें mimick नहीं कर सकते हैं: इस तरह वाक्य रचना दिखाई देता है। मुझे लगता है कि यह आईई 8 और नीचे छोड़कर हर ब्राउज़र पर काम करता है।

$(document).ready(function() { 
    var module = new Module('idcode'); 
    module.id = 'new idcode'; 
    module.title = 'new title'; 
    $('body').html(module.id + ': ' + module.title); 
}); 

function Module(id, title) { 
    return { 
    id_code: id_code, 
    _title: title, 

    get id() { 
     return id_code; 
    }, 
    set id(value) { 
     id_code = value; 
    }, 

    get title() { 
     return _title; 
    }, 
    set title(value) { 
     title = value; 
    } 
    } 
}; 
2

मुझे यह पसंद:

// Module 
var Module = function() { 

    // prive getter/setter value 
    var __value; 

    // private getter/setter method 
    var _value = function() { 
     if(!arguments.length) return __value; 
     else __value = arguments[0]; 
    }; 

    // output/public  
    return { 
     value: _value 
    }; 
} 
0

एक विश्वसनीय, अर्थ तरह से मैं इष्ट गया है setters और getters उपयोग करने के लिए है।

var myComplexObject = { 
    changelog: {}, 
    log: function(name, val) { 
    console.log("set " + name + " to " + val); 
    if (!this.changelog[name]) 
     this.changelog[name] = []; 
    this.changelog[name].push(val); 
    }, 
    set o (val) { 
    this.log("o", val); 
    }, 
    get o() { 
    console.log("You will never know the true value!"); 
    return 42; 
    } 
} 

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

myComplexObject.o = "oxygen"; 
set o to oxygen 

फिर, इस उदाहरण में, इस में मूल्य परिणाम पढ़ने का प्रयास:

var read = myComplexObject.o; 
console.log(read); 
You will never know the true value! 
42 

और, इस उदाहरण में, आपके द्वारा सेट किया गया प्रत्येक नया मान लॉग है:

myComplexObject.o = "Oh no!"; 
console.log(myComplexObject.changelog.o); 
set o to Oh no! 
["oxygen", "Oh no!"] 
संबंधित मुद्दे

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