अगर स्टेटमेंट, अच्छा अभ्यास या नहीं, तो वेरिएबल असाइन करें? [बन्द है]


113

मैं एक साल पहले क्लासिक OO भाषाओं जैसे जावा से जावास्क्रिप्ट में स्थानांतरित हुआ। निम्न कोड निश्चित रूप से जावा में अनुशंसित नहीं है (या सही भी नहीं):

if(dayNumber = getClickedDayNumber(dayInfo))
{
    alert("day number found : " + dayNumber);
}
function getClickedDayNumber(dayInfo)
{
    dayNumber = dayInfo.indexOf("fc-day");
    if(dayNumber != -1) //substring found
    {
        //normally any calendar month consists of "40" days, so this will definitely pick up its day number.
        return parseInt(dayInfo.substring(dayNumber+6, dayNumber+8));
    }
    else return false;
}

मूल रूप से मुझे सिर्फ यह पता चला कि मैं एक वैरिएबल को एक स्टेटमेंट में if if स्टेटमेंट में असाइन कर सकता हूं, और तुरंत असाइन किए गए मान को चेक कर सकता हूं जैसे कि वह बूलियन है।

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


"The following code is definitely not recommended (or event not correct) in Java..."क्या यह जावास्क्रिप्ट में भी सही है? क्योंकि, जहाँ तक मैं देख सकता हूँ, आप एक पूर्णांक ( return parseInt(...)) है अगर dayNumber != -1यह सच है, लेकिन एक बूलियन अगर यह गलत है।
डैनियल केविस्ट

जवाबों:


117

मैं इसकी सिफारिश नहीं करूंगा। समस्या यह एक सामान्य त्रुटि जहां मूल्यों की तुलना करने की कोशिश, लेकिन एक भी उपयोग करने की तरह लग रहा है, =के बजाय ==या ===। उदाहरण के लिए, जब आप इसे देखते हैं:

if (value = someFunction()) {
    ...
}

आप नहीं जानते कि क्या वे करने के लिए इसका मतलब है, या अगर वे यह लिखने का इरादा है:

if (value == someFunction()) {
    ...
}

यदि आप वास्तव में असाइनमेंट करना चाहते हैं, तो मैं एक स्पष्ट तुलना करने की सलाह दूंगा:

if ((value = someFunction()) === <whatever truthy value you are expecting>) {
    ...
}

1
@ मैथ्यू क्रुमले: यह मेरे सवाल का स्पष्ट तरीके से जवाब देता है। मैं असाइन करके चेक नहीं कर रहा हूं, लेकिन असाइनमेंट के बाद होने वाले वैल्यू का मूल्यांकन करता है। क्या यह समझ सही है?
माइकल माओ

1
@ माइकल: हाँ, यह सही है। तुलना को मूल रूप से जोड़ना सिर्फ आपके इरादों को और अधिक स्पष्ट करता है।
मैथ्यू क्रुमले

4
अंतिम उदाहरण काम नहीं करता है, हालांकि, यदि आप एक फ़ंक्शन की विफलता / सफलता के लिए परीक्षण कर रहे हैं जो एक बूलियन देता है। दूसरे शब्दों में, if (resultArr = myNeedle.exec(myHaystack)) {...}काम करते समय , if ((resultArr = myNeedle.exec(myHaystack)) === true) {...}ऐसा नहीं होता है क्योंकि परिणाम के लिए असाइनमेंट हमेशा फ़ंक्शन परिणाम नहीं होने पर भी सत्य होता है। अगर कोई भी इसका उपयोग करता है .. निर्माण, पहले परिणाम चर घोषित करना याद रखें; within var ’if कंडीशन स्टेटमेंट के भीतर कानूनी नहीं है।
विले

3
आप उपयोग कर सकते हैं if (!!(value = someFunction())), लेकिन जैसा कि आपने कहा, समस्या यह है कि आप varअंदर का उपयोग नहीं कर सकते हैं ifताकि आप या तो एक वैश्विक निर्माण कर सकें, या कुछ भी हासिल न कर सकें, क्योंकि आपको किसी भी तरह valueसे एक अलग लाइन में घोषणा करनी होगी । शर्म आती है, मुझे वास्तव में C ++ में यह निर्माण पसंद आया।
रीव

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

28

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

if (x = processorIntensiveFunction()) { // declaration inside if intended
    alert(x);
}

उस फ़ंक्शन को 2 बार चलने की अनुमति क्यों दी जानी चाहिए:

alert(processorIntensiveFunction());

क्योंकि पहला संस्करण LOOKS खराब है? मैं उस तर्क से सहमत नहीं हो सकता।


32
एक पुरानी टिप्पणी को पचाने के लिए नहीं, लेकिन मैं आपके तर्कों से सहमत नहीं हूं। पठनीय कोड को टिप्पणी की आवश्यकता के बिना खुद को समझाना चाहिए - भ्रामक कोड में एक टिप्पणी जोड़ना एक उपाय नहीं है। दूसरे भाग के लिए, जो कहता है कि विकल्प को फिर से कार्य करना है, मुझे नहीं लगता कि कोई भी ऐसा करने का इरादा रखता है। इसके बजाय आप क्या करेंगेx = processorItensiveFunction(); if(x) { alert(x); }
maksim

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

1
@maksim आपको क्यों लगेगा कि if ( ! x = anyFunction() )यह पठनीय नहीं है? इसे किसी भी टिप्पणी की आवश्यकता नहीं है।
ज्रेड्रे

यदि आप ओपीसी को ठीक करते हैं, तो अलग-अलग कौशल स्तरों के अन्य देवों के साथ काम करें (दूसरे शब्दों में, आप एक पेशेवर हैं) आप नफरत करेंगे कि यह भी संभव है।
davidjmcclelland

2
@maksim - भी आपके समाधान एक if-elseस्थिति में बहुत असुविधाजनक होगा । विचार करें- if (condition) {...} else if (x = processorIntensiveFunction()) {alert(x)} आपका पूर्व x = processorIntensiveFunction();प्रयास व्यर्थ होगा, प्रारंभिक conditionसत्य होना चाहिए ।
एड्रियन बार्थोलोम्यू

16

मैंने कई बार किया। जावास्क्रिप्ट चेतावनी को बायपास करने के लिए, मैं दो पार्न जोड़ता हूं:

if ((result = get_something())) { }

आपको इससे बचना चाहिए, यदि आप वास्तव में इसका उपयोग करना चाहते हैं, तो इसके ऊपर एक टिप्पणी लिखें कि आप क्या कर रहे हैं।


1
@SHiKKROU: मैं जावास्क्रिप्ट चेतावनियाँ कैसे देख सकता हूँ? क्या एक जावास्क्रिप्ट संकलक है? या दुभाषिया किसी प्रकार की चेतावनी उत्पन्न करेगा? मैं हर समय जावास्क्रिप्ट डिबगिंग में फ़ायरफ़ॉक्स कंसोल का उपयोग कर रहा हूं लेकिन कभी भी समान आउटपुट नहीं देखता। मेरे सीमित अनुभव के बारे में क्षमा करें।
माइकल माओ

5
@ मिसेल : JSLint ( jslint.com ) एक लोकप्रिय कार्यक्रम / पुस्तकालय है जो संभावित गलतियों या बुरे कोड के लिए जावास्क्रिप्ट कार्यक्रमों की जाँच करता है।
मैथ्यू क्रुमले

चेतावनी की जांच के लिए फायरबग और / या वेब डेवलपर एक्सटेंशन के साथ मोज़िला फ़ायरफ़ॉक्स का उपयोग करें।
मिंग-तांग

मैं बस के साथ इसे करने की कोशिश if ((a = [1, 2]).length > 0) { console.log(a); }जहां aकहीं भी अभी तक प्रारंभ नहीं किया गया है और यह वास्तव में काम किया (अच्छा! बहुत आसान regex का उपयोग कर बनाता है)। क्या यह सही है कि मुझे var|const|letयहाँ किसी की आवश्यकता नहीं है? क्या आपको पता है कि मैं इस ट्रिक के बारे में और अधिक कहाँ पढ़ सकता हूँ ?
t3chb0t

4

आप इसे जावा में भी कर सकते हैं। और नहीं, यह एक अच्छा अभ्यास नहीं है। :)

(और ===टाइप की गई समानता के लिए जावास्क्रिप्ट का उपयोग करें । जेएस पर क्रॉकफोर्ड की द गुड पार्ट्स बुक पढ़ें।)


@quixoto: क्या मैं जावा में यह ट्रिक कर सकता हूं? मुझे आश्चर्य है ... मेरे पास हाथ से jdk नहीं है इसलिए मैं जावा में एक नमूना कोड प्राप्त करने में असमर्थ हूं। मेरी खराब मेमोरी से, जावा आपको सिर्फ एक रनटाइम त्रुटि देगा यदि रिटर्निंग वैल्यू कुछ बूलियन का मूल्यांकन नहीं करता है जैसे कि सशर्त बयान, सही?
माइकल माओ

1
आह, हाँ, जावा में यह एक बूलियन प्रकार होने के लिए जाँच की जाती है। लेकिन आप कर सकते हैंif (foo = getSomeBoolValue()) { }
बेन Zotto

हाँ यह सही है। बूलियन वेरिएबल टेस्ट करने के लिए कि क्या कुछ सफल हुआ और वैल्यू को स्टोर करने के लिए दूसरा वेरिएबल। यह है कि जावा अपना काम कैसे करता है, मैं इससे बहुत परिचित हूं, इसलिए मुझे यह देखना अजीब लगता है कि जावास्क्रिप्ट एक लाइन में दो काम कर सकता है :)
माइकल माओ

@BenZotto यह अच्छा अभ्यास क्यों नहीं है? "एक चर के आकस्मिक दुरुपयोग से बचने के लिए, आमतौर पर चर को सबसे छोटे दायरे में पेश करना एक अच्छा विचार है। विशेष रूप से, आमतौर पर एक चर की परिभाषा में देरी करना सबसे अच्छा है जब तक कि कोई इसे प्रारंभिक मूल्य नहीं दे सकता ... इन दो सिद्धांतों में से एक सबसे सुंदर अनुप्रयोग एक सशर्त में एक चर घोषित करना है। ” - स्ट्रॉस्ट्रुप, "सी ++ प्रोग्रामिंग लैंग्वेज।"
जद्राके '

1
नमस्ते, मैं यहाँ n.js जावास्क्रिप्ट उपयोगकर्ता के रूप में आया था। एक मामले में यह अच्छा अभ्यास क्यों नहीं है जिसमें मुझे दर्द था: अगर (myvar = 'a test') नोड बनाता है। GLSAL वैरिएबल myvar ( nodejs.org/docs/latest-v12.x.api/globals.html # ग्लोबल्स_ग्लोबल )। इसलिए यदि आप मेरी तरह हैं और सर्वर अनुरोध को संभालने में उस चर का उपयोग करते हैं (कुछ सेकंड के बाद वापस आना जब अन्य अनुरोधों में और सामान गिर गया हो सकता है), तो आप आश्चर्यचकित हो सकते हैं कि आपको क्या परिणाम मिलेगा। तो सिफारिश है: ध्यान रखें कि यह पैटर्न नोड में एक वैश्विक चर बनाता है।
pein-consulting.de

4

एक मामला है जब आप इसे करते हैं, while-लूप के साथ ।
फ़ाइलें पढ़ते समय, आप सामान्य रूप से ऐसा करते हैं:

void readFile(String pathToFile) {
    // Create a FileInputStream object
    FileInputStream fileIn = null;
    try {
        // Create the FileInputStream
        fileIn = new FileInputStream(pathToFile);
        // Create a variable to store the current line's text in
        String currentLine;
        // While the file has lines left, read the next line,
        // store it in the variable and do whatever is in the loop
        while((currentLine = in.readLine()) != null) {
            // Print out the current line in the console
            // (you can do whatever you want with the line. this is just an example)
            System.out.println(currentLine);
        }
    } catch(IOException e) {
        // Handle exception
    } finally {
        try {
            // Close the FileInputStream
            fileIn.close();
        } catch(IOException e) {
            // Handle exception
        }
    }
}

पर देखो whileलाइन 9. वहाँ कम से -loop, एक नई लाइन पढ़ा जाता है और एक चर में संग्रहीत है, और फिर पाश की सामग्री भाग गया है। मुझे पता है कि यह एक ifकमी नहीं है , लेकिन मुझे लगता है कि थोड़ी देर के पाश को आपके प्रश्न में भी शामिल किया जा सकता है।

इसका कारण यह है कि जब FileInputStreamआप कॉल करते समय, हर बार कॉल करते हैं FileInputStream.readLine(), तो यह फ़ाइल में अगली पंक्ति को पढ़ता है, इसलिए यदि आपने इसे लूप से केवल fileIn.readLine() != nullचर को निर्दिष्ट किए बिना कॉल करने के बजाय (currentLine = fileIn.readLine()) != null, और फिर इसे कॉल किया है लूप के अंदर भी, आपको केवल हर दूसरी पंक्ति मिलेगी।

आशा है कि आप समझेंगे, और शुभकामनाएँ!


3

यदि आप जावा में भी स्टेटमेंट्स के भीतर असाइनमेंट कर सकते हैं। एक अच्छा उदाहरण कुछ पढ़ने और इसे लिखने में होगा:

http://www.exampledepot.com/egs/java.io/CopyFile.html?l=new

कोड:

// Copies src file to dst file.
// If the dst file does not exist, it is created
void copy(File src, File dst) throws IOException 
{
    InputStream in = new FileInputStream(src);
    OutputStream out = new FileOutputStream(dst);

    // Transfer bytes from in to out
    byte[] buf = new byte[1024];
    int len;
    while ((len = in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }
    in.close();
    out.close();
}

@ नाइट्रोडिस्ट: इस उदाहरण के लिए धन्यवाद। मैं वास्तव में जावा या जावास्क्रिप्ट में समर्थक नहीं हूं ... यह जानना अच्छा है कि यह दृष्टिकोण जावा में भी संभव है :)
माइकल माओ

मुझे इसका मतलब नहीं दिख रहा है। आप इसे जावा, पीएचपी और कई अन्य भाषाओं में कर सकते हैं। सवाल जावास्क्रिप्ट के बारे में था।
अपराह्न

नहीं, यह जरूरी नहीं है, आपको प्रश्न को ध्यान से पढ़ने की आवश्यकता है।
नाइट्रोडिस्ट

3

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

"प्रेरणा

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

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

और हाँ उसका उत्तर जावा कार्यान्वयन के लिए भी मान्य है। यह उदाहरण में यद्यपि एक चर के लिए सशर्त फ़ंक्शन को असाइन नहीं करता है।


1

यह अच्छा अभ्यास नहीं है। आप जल्द ही इसके बारे में भ्रमित हो जाएंगे। यह एक सामान्य त्रुटि के समान है: दुरुपयोग "=" और "==" ऑपरेटरों।

आपको इसे कोड की 2 लाइनों में तोड़ना चाहिए। यह न केवल कोड को स्पष्ट करने में मदद करता है, बल्कि भविष्य में रिफ्लेक्टर करने में भी आसान है। कल्पना कीजिए कि आप IF स्थिति बदलते हैं? आप आकस्मिक रूप से लाइन को हटा सकते हैं और आपके चर को अब इसे सौंपा गया मान नहीं मिल सकता है।


@ तन्थनघ्न: वही जिससे मैं डरता हूँ। जब मैं बूढ़ा और आलसी हो जाता हूं तो मैं कोड में अधिक टाइप नहीं करना चाहता अगर कम कीस्ट्रोक्स बस पर्याप्त होगा :)
माइकल माओ

1
नहीं, मैं भ्रमित नहीं हूं और मैं इसे हर समय करता हूं। इसके फायदे हैं।
जद्राके '

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

0

मैं इसे एक पुराने स्कूल की सी शैली पर विचार करूंगा; यह वास्तव में जावास्क्रिप्ट में अच्छा अभ्यास नहीं है इसलिए आपको इससे बचना चाहिए।


8
मैं इसे C में एक अच्छा अभ्यास नहीं मानता।
मैथ्यू क्रुमले

1
मैं इसे कई भाषाओं में एक अच्छा अभ्यास मानता हूं।
ज्रेड्रे

सिर्फ 'अच्छा अभ्यास नहीं' कहना पर्याप्त नहीं है, इमो। यह वास्तव में शिक्षा के बारे में है - यह एक बार सीखा है, और यह बात है।
मैक्स वाटरमैन


0

मैं यहां गोलंग से आया हूं, जहां कुछ देखना आम है

if (err := doSomething(); err != nil) {
    return nil, err
}

जिसमें errउस ifब्लॉक में ही स्कॉप किया जाता है । जैसे, यहाँ मैं es6 में क्या कर रहा हूँ, जो बहुत बदसूरत लगता है, लेकिन मेरे बजाय सख्त नियम नियम नहीं बनाता है, और वही प्राप्त करता है।

{
  const err = doSomething()
  if (err != null) {
    return (null, err)
  }
}

अतिरिक्त ब्रेसिज़ एक नए, उह, "लेक्सिकल स्कोप" को परिभाषित करते हैं? जिसका अर्थ है कि मैं उपयोग कर सकता हूं const, और errबाहरी ब्लॉक के लिए उपलब्ध नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.