2012-03-10 10 views
5

From Secrets of the Javascript Ninja (महान पूर्वाभ्यास Btw):क्या 'नया' गायब होने के लिए रचनाकारों की सुरक्षा करना एक अच्छा अभ्यास है?

// We need to make sure that the new operator is always used 
function User(first, last){ 
    if (!(this instanceof User)) 
    return new User(first, last); 

    this.name = first + " " + last; 
} 

var name = "Resig"; 
var user = User("John", name); 

assert(user, "This was defined correctly, even if it was by mistake."); 
assert(name == "Resig", "The right name was maintained."); 

किसी भी वास्तविक दुनिया कोड शैली गाइड सभी निर्माताओं (पहले दो लाइनों) की सुरक्षा के इस प्रकार हो जाए? मेरा मानना ​​है कि लिंटर्स User("John", "Resig") जैसे कॉल पकड़ेंगे और गायब new के बारे में चेतावनी देंगे, है ना?

+3

मुझे लगता है कि यदि आप सार्वजनिक पुस्तकालय विकसित कर रहे हैं, तो आपको केवल परेशान करने की आवश्यकता है, जहां लोग गलती से 'उपयोगकर्ता()' के बजाय 'उपयोगकर्ता() 'को कॉल कर सकते हैं। –

उत्तर

7

मुझे सलाह है कि आप सपोर्ट मोड का उपयोग करें और उस ब्राउज़र में परीक्षण करें जो इसका समर्थन करता है। उदाहरण के लिए,

function User(first, last) { 
    "use strict"; 
    this.name = first + " " + last; 
} 

यदि आप new को उपेक्षा करते हैं तो यह सख्त मोड में फेंक देगा। उदाहरण के लिए,

User("a", "b") 

फ़ायरफ़ॉक्स में TypeError फेंक देगा। यह आपको instanceof चेक के दंड का भुगतान किए बिना त्रुटियों को पकड़ने की अनुमति देता है। यह एक प्रकार की त्रुटि फेंकता है भले ही आप इसे सख्त मोड से बाहर कहते हैं। ऐसा इसलिए है क्योंकि सीधे सख्त मोड funcitons का आह्वान this वैश्विक के बजाय undefined पर बाध्य है। undefined पर एक संपत्ति सेट करने से TypeError अपवाद होता है।

+0

एक हैक की तरह थोड़ा लगता है। मुझे आश्चर्य है कि यह कोड पोर्टेबल कैसे है? –

+0

दरअसल यह दूसरी तरफ है। जो चकज प्रस्तावित कर रहा है वह इसे करने का "उचित" तरीका है (ईएस 5) और ओपी सुझाव देता है कि "हैक" है। यहां एक नज़र डालें: https://developer.mozilla.org/en/JavaScript/Strict_mode – Saebekassebil

+0

@Saebekassebil, चकज का समाधान उचित तरीका हो सकता है, लेकिन लिंक किए गए आलेख के अनुसार, सख्त मोड लगातार ब्राउज़र में समर्थित नहीं है। वे इसे स्पष्ट करते हैं - "ब्राउज़र विश्वसनीय रूप से सख्त मोड को लागू नहीं करते हैं, इसलिए अंधेरे से इस पर निर्भर न करें।"; "सख्त मोड का समर्थन नहीं करने वाले ब्राउज़र सख्त मोड कोड चलाएंगे जो ब्राउज़र से अलग व्यवहार के साथ चलाएंगे।", आदि। यदि ओपी वास्तव में इस सुविधा को लागू करना चाहता है, तो मुझे लगता है कि उसे जॉन रेसिग के समाधान का उपयोग करना चाहिए, जो सभी प्रमुख जावास्क्रिप्ट कार्यान्वयन में काम करना चाहिए । –

2

JSHint.com पर अपने कोड की जांच है, यह मुझे नहीं बताया कि मैं new कीवर्ड याद आ रही थी:

function User(first, last){ 
    this.name = first + " " + last; 
} 

var name = "Resig"; 
var user = User("John", name); 

परिणाम:

Line 2: this.name = first + " " + last; 
Missing "use strict" statement. 

Line 5: var name = "Resig"; 
Redefinition of 'name'. 

लेकिन लिंटर 'isn यहाँ बिंदु नहीं है।

चाहे यह अच्छा अभ्यास है या नहीं, हाँ यह एक अच्छा अभ्यास है क्योंकि मनुष्य लिंटर्स नहीं हैं, वे new कीवर्ड डालना भूल सकते हैं। और यहां तक ​​कि यदि एक लिटर इसके बारे में चेतावनी देता है, तो भी मैं आगे बढ़ूंगा और अपना कोड सुरक्षित रखूंगा।

सरल डालने में कुछ भी गलत नहीं है; आप अतिरिक्त स्थिति कह सकते हैं जो आपको समस्या से बचने में मदद करता है।

एक परंपरा है कि पहले अक्षर एक निर्माता समारोह के राजधानी होना चाहिए नहीं है; जिसे उसी कारण से पेश किया गया था ताकि एक जेएस डेवलपर new कीवर्ड को कभी न भूलें जब वह कहता है कि किसी फ़ंक्शन की पहली पत्र पूंजी है लेकिन सभी डेवलपर्स इसके बारे में नहीं जानते हैं (मुझे हाल ही में पता नहीं था जब मैंने जेएस को गंभीरता से खोजना शुरू किया था) यह वह जगह है जहां आप बाहरी दुनिया द्वारा निर्दिष्ट नहीं किया गया है, तो आप इसे अपने आप डालकर सुरक्षित रखें।

+0

कोड कन्स्ट्रक्टर के रूप में नहीं कहा जाता है, जब यह 'नए' को कॉल जारी करता है, ताकि यह वही काम करता है यदि आप 'नया उपयोगकर्ता (x, y) 'या' उपयोगकर्ता (x, y) करते हैं '। – Lucero

+0

मुझे पूरा यकीन था कि मैंने कहीं एक लिटर देखा है जो पहले अक्षर-पूंजी नियम को कन्स्ट्रक्टर उपयोग का अनुमान लगाने के लिए विचार करता था, और 'नया' गायब होने की जांच करता था। शायद मैं भयावह हूँ। – ripper234

+1

@ ripper234: यदि आपके पास हमेशा लिटर उपलब्ध है या आप इसे हमेशा इस्तेमाल करते हैं और आप दूसरों को अपने कोड का उपयोग लिंटर्स के साथ करने की उम्मीद करते हैं, तो कोई समस्या नहीं है, सबकुछ हमेशा ठीक रहेगा :) – Sarfraz

1

कोड चेतावनी दी doens't, यह सिर्फ new फोन करता है तो यह पहली जगह में उपयोग नहीं किया गया है, ताकि बुला User(x, y) आंतरिक रूप से एक new User(x, y) कर खत्म हो जाएगा।

उसने कहा, मुझे इस प्रकार के पारदर्शी सुधार पसंद नहीं हैं। रक्षात्मक कोडिंग ठीक है (उदाहरण के लिए एक त्रुटि फेंकना), लेकिन मुझे कोड करना पसंद नहीं है जो मैं करना चाहता हूं (या मैंने जो किया हो, वह गलती से हो सकता है, जैसे कि मैं एक फ़ंक्शन कॉल करना चाहता हूं, user)।


हम (हमारी कंपनी के रूप में) एक घटक और templating प्रणाली हम आंतरिक रूप से उपयोग करने के संयोजन में हालांकि एक ही जावास्क्रिप्ट की "सुविधा" का उपयोग करते हैं।

हमारे "घटकों" (एक विशिष्ट डीओएम ऑब्जेक्ट से जुड़े व्यवहार के साथ जेएस ऑब्जेक्ट) इस शैली में बनाए जाते हैं: new MyComponent(domObject) - यह घटक बनाता है और इसे डीओएम तत्व (जहां यह घटनाओं आदि के लिए सुन सकता है) से जोड़ता है।

हम एक टेम्पलेटिंग इंजन का भी उपयोग करते हैं जो जेएस फ़ंक्शंस को संकलित करता है, ताकि आप टेम्पलेट को इस तरह के फ़ंक्शन के रूप में कॉल कर सकें: myTemplate(someData) - यह दिए गए टेम्पलेट को HTML स्ट्रिंग में प्रस्तुत करता है। टेम्पलेट्स आंशिक कॉल भी कर सकते हैं, जो स्पष्ट रूप से HTML स्ट्रिंग्स को लौटने वाले सामान्य कार्य हैं।

सीधे घटकों के लिए एचटीएमएल उत्पन्न करने के लिए, घटक कन्स्ट्रक्टर "पहचान" का उपयोग करेगा चाहे इसे new के माध्यम से बुलाया गया हो या कन्स्ट्रक्टर या टेम्पलेट के रूप में कार्य न किया जाए। जब यह टेम्पलेट के रूप में काम करता है, तो यह हमारे रूट तत्व (data-component हमारे मामले में) में एक विशेष विशेषता जोड़ देगा ताकि एक फिक्सअप बाद में किया जा सके जहां जेनरेट किया गया HTML एक डोम पेड़ में परिवर्तित हो जाता है और फिर इस विशेषता वाले सभी DOM तत्व स्वचालित रूप से होते हैं उनके लिए उत्पन्न घटक प्राप्त करना (इस बार new का उपयोग करना)।

यह केवल एक उदाहरण है कि आप इस तरह की भाषा संरचनाओं का लाभ कैसे उठा सकते हैं।

1
बस मस्ती के लिए

:

function User(first,last,id){ 
    User.Instance = User.Instance|| function(firstname,lastname,id){ 
     this.firstname = firstname || 'nofirstname'; 
     this.lastname = lastname || 'nolastname'; 
     this.id = id || 0; 
     if (!User.Instance.prototype.nameUpper){ 
     User.Instance.prototype.nameUpper = function(){ 
        return this.name.toUpperCase(); 
     }; 
     User.Instance.prototype.resetId = function(){ 
        this.id = 0; return this; 
     }; 
     User.Instance.prototype.toString = function(){ 
      return [this.id,': ', 
        this.firstname[0].toUpperCase(), 
        this.firstname.slice(1), 
        ' ', 
        this.lastname[0].toUpperCase(), 
        this.lastname.slice(1)].join(''); 
     }; 
     } 
    } 
    return new User.Instance(first,last,id); 
} 
//usage 
var pete = User('pete','johanssen',1), 
    jean = User('jean','harlowe',2), 
    mary = new User('mary','wsnovsky',3); 
console.log(pete); //=> 1: Pete Johanssen' 
console.log(mary); //=> 3: Mary Wsnovsky' 

अपने प्रश्न के संबंध में: यह भी new कीवर्ड भूल के खिलाफ की रक्षा के लिए एक तरीका हो सकता है मैं विचार करेगा 'अच्छा प्रैक्टिस' काफी प्रामाणिक/अनुमान। क्या यह हर दिन गायों की आंख खाने के लिए 'अच्छा अभ्यास' है? अगर मैं इसका उत्तर देना चाहता था, तो मैं नहीं कहूंगा, लेकिन मुझे यकीन है कि दुनिया में हर कोई इससे सहमत नहीं होगा। भूल गए new कीवर्ड को रोकने के लिए आपके द्वारा प्रदर्शित पैटर्न का उपयोग करना अच्छा या बुरा नहीं है। यह आपके द्वारा निर्धारित मानदंडों पर निर्भर करता है: क्या आप एक निश्चित कठोरता को लागू करना चाहते हैं, या आप अपने या अपने सहयोगियों के खिलाफ सुरक्षा करना चाहते हैं? क्या पैटर्न कम प्रदर्शन करेगा? क्या chukj की सख्तता सभी स्थितियों में काम करेगी, और यदि नहीं, तो क्या यह आपके लिए पर्याप्त होगा?

मुझे पसंद है चीजों में से एक और जावास्क्रिप्ट में नफरत इसकी लचीलापन है। JSLint, जहाँ तक मैं डगलस Crockford की व्याख्यान से समझ में आया, एक समान प्रोग्रामिंग शैली करने के लिए आप के लिए मजबूर करने डिज़ाइन किया गया है - उनके ही शब्दों में:

jslint का उपयोग कर आप

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

कभी-कभी जावास्क्रिप्ट समुदाय 'जावास्क्रिप्ट संप्रदाय का चर्च' जैसा व्यवहार करता है। इसमें हम बहुत सख्त विश्वासियों को पाते हैं, जिनके लिए कानून का कानून कानून है, और इसके लिए हर विचलन एक मुख्य पाप है (जिसके लिए "सख्त" का विशेष रूप से आविष्कार किया जा सकता है;)। अन्य एक और व्यावहारिक पथ का पालन करें।नियमित चर्च के लोग और लोग कभी नहीं दिखते हैं। Schisms उभरा। कुछ इस चर्च को छोड़ने और एक नया पाया जाने की योजना बना रहे हैं, उदा। जहां classes की अनुमति है और अच्छे और पवित्र माना जाता है।

जैसा कि अब तक स्पष्ट हो सकता है: मुझे लगता है कि 'अच्छी प्रैक्टिस' जैसी कोई चीज़ नहीं है। या इसे अधिक छद्म-धार्मिक शब्दों में वाक्यांश के लिए: अच्छा अभ्यास दर्शक की आंखों में है।

+0

हालांकि वास्तव में कोई जवाब नहीं है ... फिर भी, मैं डाउनवोट नहीं करूँगा। – ripper234

+0

जैसा मैंने कहा, बस मस्ती के लिए। लेकिन मैंने आपके प्रश्न का उत्तर देने के लिए भी अपना जवाब संपादित किया। – KooiInc

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