2010-07-10 8 views
5

मैं यह देखने की कोशिश कर रहा हूं कि मैं अपनी जावास्क्रिप्ट ऑब्जेक्ट्स को यथासंभव सहजता से बना सकता हूं, जबकि यह सुनिश्चित कर रहा हूं कि यह यथासंभव 'सही' है। मैं क्रॉकफोर्ड के JSLint.com के माध्यम से विभिन्न परिदृश्यों का एक गुच्छा चला रहा हूं और इसमें बहुत भाग्य नहीं है। मुझे एक त्रुटि ठीक लगती है, फिर परिवर्तन के कारण कोई और पॉप अप हो जाता है। नीचे जितना अच्छा हो उतना अच्छा है। किसी के पास इस पर कोई और लेना है?जावास्क्रिप्ट ऑब्जेक्ट बनाने का सबसे अच्छा तरीका क्या है जिससे यह काम करता है और जेएसलिंट पास करता है?

function gizmo(id) { 

    /* private variables */ 

    var myId = id; 

    /* private methods */ 

    var init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    var setId = function (newId) { 
    myId = newId; 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 

// creating an instance of gizmo 

var myGizmo = gizmo(-2); 
console.log(myGizmo.getId()); // outputs 1 

myGizmo.setId(5); 
console.log(myGizmo.getId()); // outputs 5 

myGizmo.incrementId(2); 
console.log(myGizmo.getId()); /// outputs 7 

यह अच्छी तरह से काम करने लगता है:

यह एक विशिष्ट तरीका मैं एक वस्तु की संरचना है। हालांकि, जब मैं जेएसलिंट के माध्यम से इसे चलाता हूं, तो यह मुझे एक त्रुटि देता है जिसमें कहा गया है कि मेरे दो निजी कार्य 'लागू ग्लोबल्स' हैं।

सबसे अच्छा मैं के साथ इस तरह चर के साथ शीर्ष पर मेरे कार्यों की घोषणा करने के लिए है ऊपर आ सकते हैं:

function gizmo(id) { 

    /* private variables */ 

    var myId = id, 
     init, 
     setId; 

    /* private methods */ 

    init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    setId = function (newId) { 
    myId = newId; 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 
+2

यह सलाह के रूप में इतना जवाब नहीं है। जेएसलिंट के बारे में ज्यादा चिंता मत करो। मुझे अक्सर यह बहुत सख्त लगता है। इसके बजाय प्रोग्रामिंग पर ध्यान केंद्रित करें। उस ने कहा, मैं दूसरों को सर्वोत्तम अभ्यास पर चर्चा करने दूँगा। – TNi

+0

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

+0

समस्या init और आपके कार्यों का क्रम है। ऑब्जेक्ट को वापस करने से पहले इनिट को सही तरीके से ले जाएं। इसके अलावा मुझे नहीं लगता कि आपको फ़ंक्शन init की आवश्यकता है। हो सकता है कि चीजों को अलग करने के लिए एक स्व-निष्पादन और अज्ञात एफएन के रूप में। – galambalazs

उत्तर

1

मुझे यकीन है कि यह जेएसलिंट में एक बग है। इसने अभी तक setId नहीं देखा है, इसलिए यह मानता है कि यह वैश्विक है। लेकिन हकीकत में, इससे कोई फर्क नहीं पड़ता, क्योंकि एस ECMAScript 5 10.5 प्रति फहराए गए हैं। इसका मतलब है आपका पहला उदाहरण और दूसरा वही अर्थात् समान है। फ़ंक्शन में एक स्थानीय परिवर्तनीय घोषणा कहीं भी को संसाधित किया जाता है, और बाध्यकारी प्रारंभ में undefined मान होने के लिए सेट किया गया है। लेकिन उस समय तक फ़ंक्शन (उदा। Init) वास्तव में चलता है, बंद-इन मान अब undefined नहीं है।

कि setId शुरू में अपरिभाषित है देखने के लिए, लेकिन कभी नहीं एक वैश्विक को संदर्भित करता है, इस परीक्षण कार्य करें:

function setId() 
{ 
    alert("Global setId"); 
} 
function f() 
{ 
    var init = function() 
    { 
    setId(); 
    } 
    alert(typeof(setId)); 
    init(); 
    var setId = function() 
    { 

    } 
} 

यह अपरिभाषित सूचित करेंगे, तो एक TypeError त्रुटि फेंक देते हैं।

+0

+1, मुझे hoisting के बारे में पता नहीं था। मैंने हमेशा यह माना कि आपको चीजों को क्रम में घोषित करना था। – gradbot

+0

यदि आप उन्हें क्रॉस-ब्राउज़र काम करना चाहते हैं तो आपको उन्हें घोषित करना होगा। – lawnsea

+0

@lawnsea, कौन सा ब्राउज़र अलग-अलग व्यवहार करता है, और कैसे? –

0

मैं JSlint के बारे में पता नहीं है, लेकिन पढ़ने "जावास्क्रिप्ट अच्छा भागों" के बाद, मैं हमेशा वस्तुओं को अक्षर के रूप में घोषित करता हूं।

जैसे:

Mogwai={ 
    has_crazy_thoughts:True, 
    reacts_to_water:True, 
    name: 'Gizmo', 
    eat:function(food){ 
    // code 
    }, 
    become_gremlin:function(){ 
    // code 
    }, 
    cause_havoc:function(){ 
    // code 
    } 
} 

आप वास्तव में किसी भी वस्तुओं से ऊपर की घोषणा नहीं कर रहे हैं। बस एक समारोह। आंतरिक कार्य वास्तव में जावास्क्रिप्ट में मौजूद नहीं हैं - यह जावा की तरह नहीं है।

संपादित करें: मैं उपर्युक्त पुस्तक (संबद्धता के बिना) की अत्यधिक अनुशंसा करता हूं: http://oreilly.com/catalog/9780596517748 ... यह डगलस क्रॉकफ़ोर्ड द्वारा लिखा गया है, जिसने हमें जेएसलिंट लाया।

+1

मेरे पास पुस्तक है। और हाँ, यह अच्छा है। मेरा उदाहरण उपरोक्त का उपयोग करके निजी चर और फ़ंक्शन बनाता है, जो कुछ भी उस पुस्तक में क्रॉकफोर्ड चला जाता है। अपने उदाहरण के साथ, ऑब्जेक्ट अक्षर का उपयोग करके, मेरे पास निजी चर या फ़ंक्शन बनाने का कोई तरीका नहीं है। –

+0

वास्तव में, आप एक वस्तु घोषित कर रहे हैं। आप ऑब्जेक्ट की घोषणा कर रहे हैं, साथ ही साथ तीन फ़ंक्शंस, दो बूलियन और एक स्ट्रिंग, ऑब्जेक्ट के गुणों में भरे हुए हैं। – icktoofay

+0

इसके अलावा, 'ट्रू' और 'गलत' जावास्क्रिप्ट में लोअरकेस हैं। – icktoofay

3

जेएसलिंट उम्मीद करता है कि इसे init में संदर्भित करने से पहले परिभाषित किया जाए।

यह जेएसलिंट पास करता है।

function gizmo(id) { 

    /* private variables */ 

    var myId = id; 

    /* private methods */ 

    var setId = function (newId) { 
    myId = newId; 
    }; 

    var init = function() { 
    if (myId < 1) { 
     setId(1); 
    } 
    }; 

    // run 'constructor' 
    init(); 

    /* public methods */ 

    return { 
    getId: function() { 
     return myId; 
    }, 
    setId: function (newId) { 
     setId(newId); 
    }, 
    incrementId: function (inc) { 
     setId(myId + inc); 
    } 
    }; 
} 
+0

यदि मैं फ़ंक्शन setId() का उपयोग करके अपना फ़ंक्शन परिभाषित करता हूं तो यह कोई फर्क नहीं पड़ता है, मुझे जेएसलिंट में एक ही लागू वैश्विक त्रुटि मिलती है। –

+0

मैंने बस जेएसलिंट के माध्यम से इसे चलाया और यह पारित हो गया। इसे अपनी वेबसाइट पर आज़माएं। http://www.jslint.com/ – gradbot

+1

'setId' कभी भी वैश्विक को संदर्भित नहीं करता है। उछाल के कारण, यह हमेशा स्थानीय चर को संदर्भित करता है। यह सच है कि इस स्थानीय चर का मूल्य प्रारंभ में अनिर्धारित है, लेकिन यह अप्रासंगिक है क्योंकि इसे परिभाषित किया जाता है जब 'init' कहा जाता है। –

0

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

सबसे पहले, जिस तरह से आप अपनी वस्तुएं बना रहे हैं, वह Module Pattern की याद दिलाता है। जहां तक ​​मुझे याद है, मैंने जिस लेख से लिंक किया है वह उस बारे में एक बहुत अच्छा पढ़ा है। दूसरा, शायद आप instantiate your objects पर एक अलग तरीका पसंद करेंगे। वह लेख आपको थोड़ा अलग लेता है।

+0

कूल। उस पर रेसिग की पोस्ट पढ़ना। धन्यवाद। –

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