क्या जावास्क्रिप्ट में "शॉर्ट-सर्किट" मूल्यांकन है?


101

मैं यह जानना चाहूंगा कि क्या जावास्क्रिप्ट में C # में && संचालक की तरह "शॉर्ट-सर्किट" मूल्यांकन है। यदि नहीं, तो मैं जानना चाहूंगा कि क्या कोई वर्कअराउंड है जो अपनाने के लिए समझ में आता है।


2
आपका स्वागत है। मैंने https://www.google.com/search?q=site:stackoverflow.com+%sखोजों को गति देने के लिए खोज शॉर्टकट (Chrome / Firefox) के रूप में जोड़ा है ।
रॉब डब्ल्यू

इसके अलावा यहां मेरे प्रश्न का उत्तर है। developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
जिब्बो

जवाबों:


118

हां, जावास्क्रिप्ट में "शॉर्ट-सर्किट" मूल्यांकन है।

if (true == true || foo.foo){
    // Passes, no errors because foo isn't defined.
}

लाइव डेमो

if (false && foo.foo){
    // Passes, no errors because foo isn't defined.
}

लाइव डेमो


8
शॉर्ट सर्किट तो यह जेएस में मानक है?
जिब्बो

1
धन्यवाद gdoron, कृपया मेरी मदद को समझने के लिए ... सी # में मैं द्विआधारी ऑपरेटर की तरह और दोनों बहुत भी है संकार्य सी में पारित करने के लिए, के बजाय साथ && सच होना चाहिए
GibboK

1
@GibboK। फिर, जाहिर है, Short-circuitउस तर्क ऑपरेटर के साथ नहीं हो सकता । बस इसे स्वयं आज़माएं। मेरे डेमो का उपयोग करें।
गर्डोरन

2
@ GibboK: इस ऑपरेटर संदर्भ को देखें । और हाँ, जेएस में एक बाइनरी और ऑपरेटर भी है।
बर्गी

5
@GibboK। हाँ मानक में! लेकिन जावास्क्रिप्ट कार्यान्वयन में JIT- संकलन-जादू के रूप में अच्छी टिप्पणी, कोई वास्तव में जानना चाहता है कि क्या कुछ "मानक" है, या संभावित रूप से कार्यान्वयन के अधीन है। जिस तरह से बाइनरी लॉजिकल ऑपरेटर्स के साथ एक स्टेटमेंट स्टेटमेंट का मूल्यांकन किया जाता है और (शॉर्ट- क्यूरकिट
मानवता 11

23

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


अब तक हम जो जानते थे (हमने सोचा था):

पहले हम उस व्यवहार का निरीक्षण करें जिससे हम सभी परिचित हैं, if()ब्लॉक के अंदर , जहां हम &&यह जांचने के लिए उपयोग करते हैं कि क्या दो चीजें हैं true:

if (true && true) {
   console.log('bar');
} 

: अब, अपने पहले वृत्ति शायद कहने के लिए है 'आह हाँ, काफी सरल, कोड बयान दोनों अगर कार्यान्वित expr1और expr2के रूप में मूल्यांकन किया जाता है true'

खैर, हाँ और नहीं। आप तकनीकी रूप से सही हैं, यह आपके द्वारा वर्णित व्यवहार है, लेकिन यह बिल्कुल नहीं है कि कोड का मूल्यांकन कैसे किया जाता है और हमें पूरी तरह से समझने के लिए गहराई से खोदना होगा।


वास्तव में किस प्रकार की जाती है &&और ||व्याख्या की ?:

यह देखने का समय है "हुड के तहत इंजन "। आइए इस व्यावहारिक उदाहरण पर विचार करें:

function sanitise(x) {
  if (isNaN(x)) {
    return NaN;
  }
  return x;
}

let userinput = 0xFF; // as an example
const res = sanitise(userinput) && userinput + 5

console.log(res);

खैर परिणाम है 260.. लेकिन क्यों? उत्तर प्राप्त करने के लिए, हमें यह समझने की आवश्यकता है कि शॉर्ट-सर्किट मूल्यांकन कैसे काम करता है।

द्वारा MDN परिभाषा&& में ऑपरेटर expr1 && expr2followingly निष्पादित किया जाता है:

अगर रिटर्न में expr1परिवर्तित किया जा सकता trueहै expr2; और, रिटर्न expr1

तो इसका मतलब है, हमारे व्यावहारिक उदाहरण में, const resनिम्न तरीके से मूल्यांकन किया गया है:

  1. आह्वान expr1-sanitise(0xFF)
  2. 0xFF 250 के लिए एक वैध हेक्साडेसिमल संख्या है, अन्यथा मैं वापस आ जाता NaN
  3. expr1एक "truthy" मान दिया, निष्पादित करने का समय expr2 (अन्यथा मैं रोक चाहते हैं के रूप में NaNfalsy है)
  4. चूंकि userinputtruthy (एक संख्या) है, मैं जोड़ सकते हैं +5यह करने के लिए
  • "सत्य" का अर्थ है कि अभिव्यक्ति का मूल्यांकन सत्य के रूप में किया जा सकता है। यहां सत्य और मिथ्या भावों की सूची दी गई है ।

इसलिए यहां, हम ऑपरेटर के एक सरल उपयोग के साथ अतिरिक्त ifब्लॉक और आगे की isNaNजांच से बचने में सक्षम थे &&


यह वास्तव में कैसे काम करता है:

अब तक, हमारे पास कम से कम एक तस्वीर होनी चाहिए कि कैसे ऑपरेटर काम करते हैं। सार्वभौमिक नियम इस प्रकार है:

  • (some falsy expression) && expr मिथ्या अभिव्यक्ति का मूल्यांकन करेंगे
  • (some truthy expression) || expr सत्य अभिव्यक्ति का मूल्यांकन करेगा

बेहतर समझ के लिए यहां कुछ और उदाहरण दिए गए हैं:

function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }

if ( a() && b() ){
     console.log('foobar'); 
}

//Evaluates a() as false, stops execution.

function a() { console.log('a'); return false; }
function b() { console.log('b'); return true; }

if ( a() || b() ){
     console.log('foobar'); 
}

/* 1. Evaluates a() as false
   2. So it should execute expr2, which is `b()`
   3. b() returned as true, executing statement `console.log('foobar');`
*/


एक आखिरी pesky, लेकिन बहुत महत्वपूर्ण बात [संचालक प्राथमिकता]:

अच्छा, उम्मीद है कि आप इसे लटका रहे हैं! अंतिम चीज जो हमें जानने की जरूरत है, वह ऑपरेटर की पूर्ववर्तीता के बारे में एक नियम है, जो है:

  • &&ऑपरेटर हमेशा से पहले मार डाला जाता है ||ऑपरेटर।

निम्नलिखित उदाहरण पर विचार करें:

function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}

console.log(a() || b() && c());

// returns a() and stops execution

यह कुछ के रूप में शायद भ्रमित करने के रूप में वापस आ जाएगी a()। कारण काफी सरल है, यह सिर्फ हमारी आंख-दृष्टि है जो हमें धोखा दे रही है, क्योंकि हम बाएं से दाएं पढ़ने के आदी हैं। आइए console.log()और न लें और विशुद्ध रूप से मूल्यांकन पर ध्यान केंद्रित करें

true || false && false

अब इसके चारों ओर अपना सिर लपेटने के लिए:

  1. हमने कहा कि &&ऑपरेटर की पूर्वता है, इसलिए इसका मूल्यांकन पहले की तरह किया जाता है। मूल्यांकन की बेहतर कल्पना करने में हमारी मदद करने के लिए, परिभाषा के बारे में सोचें

    expr1 && expr2

    कहाँ पे:

    • expr2 है false
    • expr1 है true || false
  2. तो यह मुश्किल हिस्सा था, अब true || falseमूल्यांकन किया जाता है ( expr1- बाईं ओर &&)।

    • यह देखते हुए ||ऑपरेटर निष्पादन करना बंद कर दे expr1 || expr2में expr1truthy के रूप में मूल्यांकन करता है, expr1मार डाला जाता है और कोड निष्पादन बंद हो जाता है।
  3. लौटाया गया मान है true

खैर .. यह बहुत अजीब था, सभी कुछ अजीब नियमों और शब्दार्थ के कारण। लेकिन याद रखें, आप हमेशा गणित में जैसे() - से ऑपरेटर पूर्वता से बच सकते हैं

function a() { console.log('a'); return true;}
function b() { console.log('b'); return false;}
function c() { console.log('c'); return false;}

console.log((a() || b()) && c());

/* 1. The () escape && operator precedence
   2. a() is evaluated as false, so expr2 (c()) to be executed
   3. c()  
*/


मैं 1) "संकलक" शब्द का उपयोग नहीं करूंगा। "इंजन" अधिक सटीक है। 2) के बारे में बात नहीं expr1और expr2 या condition1या जो कुछ भी, कि सिर्फ भ्रामक है। एक के लिए तय है, आप भी स्थानीय चर पेश कर सकते हैं, जैसे। const expr1 = true; if(expr1 && ...)
जोनास विल्म्स

@JonasWilms इनपुट के लिए धन्यवाद, तदनुसार उत्तर में संशोधन किया गया।
सैमुअल हुल्ला

1
यह अभी भी पूछे गए सवाल का सीधे जवाब नहीं देता है।
केविन बी

7
यह सबसे अच्छा "महान उत्तर है जो स्पष्ट रूप से उस प्रश्न का उत्तर नहीं देता है" जो मैंने कभी देखा है ...
गेरार्डो फर्टाडो

1
यह एक गहरी व्याख्या के साथ सही उत्तर है, इसे वर्तमान में की तुलना में बहुत अधिक स्वीकृत और उत्क्रमित माना जाना चाहिए!
अलेक्जेंडर किम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.