जावास्क्रिप्ट या ()) चर असाइनमेंट स्पष्टीकरण


351

जावास्क्रिप्ट के इस टुकड़े को देखते हुए ...

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f = a || b || c || d || e;

alert(f); // 4

क्या कोई मुझे बता सकता है कि इस तकनीक को क्या कहा जाता है (मेरा सबसे अच्छा अनुमान इस प्रश्न के शीर्षक में है!)। और कैसे / क्यों यह ठीक काम करता है?

मेरी समझ यह है कि वेरिएबल fको पहले वैरिएबल का निकटतम मान (बाएं से दाएं) सौंपा जाएगा, जिसमें एक ऐसा मान है जो या तो अशक्त या अपरिभाषित नहीं है, लेकिन मैं इस तकनीक के बारे में ज्यादा संदर्भ सामग्री खोजने में कामयाब नहीं हुआ हूं और है देखा यह बहुत इस्तेमाल किया।

इसके अलावा, क्या यह तकनीक जावास्क्रिप्ट के लिए विशिष्ट है? मुझे पता है कि PHP में ऐसा ही कुछ करने का परिणाम स्वयं के fबजाय वास्तविक बूलियन मूल्य होगा d


4
पुराना सवाल है, लेकिन PHP के संबंध में, एक निर्माण है जिसका आप उपयोग कर सकते हैं $f=$a or $f=$b or $f=$c; // etc:। PHP में ||ऑपरेटर और ऑपरेटर दोनों हैं or, जो एक ही काम करते हैं; हालांकि orमूल्यांकन के बाद मूल्यांकन किया जाता है जबकि ||पहले मूल्यांकन किया जाता है। यह भी आपको दिलेर शैली प्रदान करता है$a=getSomething() or die('oops');
मैनजियो

1
पीएचपी 5.3 में आप टर्नरी ऑपरेटर के मध्य भाग को छोड़ सकते हैं, इसलिए उससे आधार ... आप इसे कुछ इस तरह से भी छोटा कर सकते हैं: $f = $a ?: $b ?: $c;
Rei

1
PHP 7 के रूप में आप इसके लिए उपयोग कर सकते हैं ??$a = $b ?? 'default'
स्पेंसर रस्किन

@SpencerRuskin $aका मान असाइन किया जाएगा $bयदि $bसत्य है, अन्य 'default'?
ओल्डबॉय

ये सही है। इस पृष्ठ पर अशक्त सहवर्ती
स्पेंसर रस्किन

जवाबों:


212

स्पष्टीकरण के लिए शॉर्ट-सर्किट मूल्यांकन देखें । यह इन ऑपरेटरों को लागू करने का एक सामान्य तरीका है; यह जावास्क्रिप्ट के लिए अद्वितीय नहीं है।


57
बस 'गोच' को ध्यान में रखें जो कि आखिरी है, हमेशा असाइन किया जाएगा भले ही वे सभी अपरिभाषित, अशक्त या झूठे हों। आपके द्वारा ज्ञात कुछ भी निर्धारित करना श्रृंखला के अंत में गलत, अशक्त या अपरिभाषित नहीं है, यह संकेत देने का एक अच्छा तरीका है कि कुछ भी नहीं मिला।
एरिक रेपेने

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

9
वास्तव में, आप कर सकते हैं if(true == f), जो कि जैसा है if(f): परीक्षा उत्तीर्ण होगी। यदि आप भी इस प्रकार का परीक्षण करना चाहते हैं f, तो सख्त तुलना का उपयोग करें: if(true === f)जो वास्तव में विफल हो जाएगा।
Alsciende

5
हां, शॉर्ट-सर्किट मूल्यांकन आम है। लेकिन यहां अंतर उस तरह से निहित है जिस तरह से जावास्क्रिप्ट अंतिम मूल्य देता है जिसने निष्पादन को रोक दिया। @ अनुराग का जवाब यह समझाने का बेहतर काम करता है।
बेन .12

निश्चित नहीं है कि शुरुआती लोगों के लिए यह सबसे अच्छा स्पष्टीकरण है। मैं सुझाऊँगा: javascript.info/logical-operators
csguy

198

यह डिफ़ॉल्ट मान असाइन करने के लिए बनाया गया है , इस मामले में y, यदि xचर गलत है , तो इसका मूल्य ।

जावास्क्रिप्ट में बूलियन ऑपरेटर एक ऑपरेंड वापस कर सकते हैं, और हमेशा अन्य भाषाओं की तरह बूलियन परिणाम नहीं होता है।

तार्किक या ऑपरेटर ( ||) अपने दूसरे ऑपरेंड का मूल्य लौटाता है, यदि पहला वाला गलत है, अन्यथा पहले ऑपरेंड का मूल्य वापस आ जाता है।

उदाहरण के लिए:

"foo" || "bar"; // returns "foo"
false || "bar"; // returns "bar"

Falsy मूल्यों जो लोग करने के लिए मजबूर कर रहे हैं falseजब बूलियन संदर्भ में प्रयोग किया है, और वे कर रहे हैं 0, null, undefined, एक खाली स्ट्रिंग, NaNऔर निश्चित रूप से false


1
+1 क्या कोई अन्य ऑपरेटर ऐसा है? या ||अनन्य है।
ऑस्करराइज

9
@Support (@Oscar): लॉजिकल &&ऑपरेटर का एक समान व्यवहार होता है, यह पहले ऑपरेंड के मूल्य को लौटाता है यदि यह स्वयं गलत है और दूसरे ऑपरेटर के मूल्य को लौटाता है, केवल अगर पहला सत्य है , जैसे("foo" && "bar") == "bar"(0 && "bar") == 0
सीएमएस

12
झूठा वास्तव में तकनीकी शब्द है।
चोसपंडियन

8
इसलिए हमने इस पोस्ट में ||, &&, "झूठा" और "सच में" सीखा। "छिपे हुए" उपहारों के साथ सर्वश्रेष्ठ उत्तर।
एलेक्स

4
@Alex एनबी: "Truthy" ( "सच"!)
बम्पी

183

Javacript तार्किक ऑपरेटरों के लिए शॉर्ट-सर्किट मूल्यांकन का उपयोग करता है ||और &&हालाँकि, यह अन्य भाषाओं के लिए अलग है कि यह अंतिम मूल्य का परिणाम देता है जो ए true, या falseमान के बजाय निष्पादन को रोक देता है ।

जावास्क्रिप्ट में निम्नलिखित मानों को गलत माना जाता है।

  • असत्य
  • शून्य
  • "" (खाली स्ट्रिंग)
  • 0
  • नेन
  • अपरिभाषित

ऑपरेटर की पूर्ववर्ती नियमों को अनदेखा करना , और चीजों को सरल रखना, निम्नलिखित उदाहरण बताते हैं कि कौन सा मूल्यांकन मूल्यांकन रोक दिया, और परिणामस्वरूप वापस आ जाता है।

false || null || "" || 0 || NaN || "Hello" || undefined // "Hello"

पहले 5 मान तक NaNगलत होते हैं, इसलिए इनका मूल्यांकन बाएं से दाएं तक किया जाता है, जब तक कि यह पहले "Hello"सत्य मूल्य से पूरा नहीं हो "Hello"जाता है - जो पूरी अभिव्यक्ति को सच बनाता है, इसलिए आगे कुछ भी मूल्यांकन नहीं किया जाएगा, और अभिव्यक्ति के परिणामस्वरूप वापस आ जाता है। । इसी तरह, इस मामले में:

1 && [] && {} && true && "World" && null && 2010 // null

पहले 5 मान सभी सत्य हैं और इसका मूल्यांकन तब तक किया जाता है जब तक कि यह पहले nullमिथ्या मूल्य ( ) को पूरा न कर दे, जो कि अभिव्यक्ति को गलत बनाता है, इसलिए 2010अब इसका मूल्यांकन नहीं किया nullजाता है , और अभिव्यक्ति के परिणामस्वरूप वापस आ जाता है।

आपके द्वारा दिया गया उदाहरण असाइनमेंट करने के लिए जावास्क्रिप्ट की इस संपत्ति का उपयोग कर रहा है। इसका उपयोग कहीं भी किया जा सकता है जहां आपको मूल्यों के एक समूह के बीच पहली सच्चाई या मिथ्या मूल्य प्राप्त करने की आवश्यकता होती है। इस कोड के नीचे मूल्य प्रदान करेंगे "Hello"करने bके बजाय अगर-किसी और के चेक करने का, के रूप में यह आसान एक डिफ़ॉल्ट मान आवंटित करने के लिए बनाता है।

var a = false;
var b = a || "Hello";

आप नीचे दिए गए उदाहरण को इस सुविधा का शोषण कह सकते हैं, और मेरा मानना ​​है कि यह कोड को पढ़ने में कठिन बनाता है।

var messages = 0;
var newMessagesText = "You have " + messages + " messages.";
var noNewMessagesText = "Sorry, you have no new messages.";
alert((messages && newMessagesText) || noNewMessagesText);

अलर्ट के अंदर, हम जाँचते हैं कि messagesक्या गलत है, और यदि हाँ, तो मूल्यांकन करें और वापस लौटें noNewMessagesText, अन्यथा मूल्यांकन करें और वापस लौटें newMessagesText। चूंकि यह इस उदाहरण में गलत है, इसलिए हम noNewMessagesText और अलर्ट पर रुकते हैं "Sorry, you have no new messages."


36
निम्नलिखित स्पष्टीकरण के कारण मेरी राय में यह सबसे अच्छा उत्तर है:However, it's different to other languages in that it returns the result of the last value that halted the execution, instead of a true, or false value.
मस्तज़ी

1
@ मस्तजी हां, इसे बोल्ड फॉन्ट IMHO में जाना चाहिए।
noober

6
उत्तर होना चाहिए, यह परीक्षण मामलों पर चुने जा रहे मूल्यों को दर्शाता है।
दादन

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

49

जावास्क्रिप्ट चर टाइप नहीं किए गए हैं, इसलिए च को एक पूर्णांक मान सौंपा जा सकता है, भले ही यह बूलियन ऑपरेटरों के माध्यम से सौंपा गया हो।

f को निकटतम मान दिया गया है जो असत्य के बराबर नहीं है । तो 0, झूठे, अशक्त, अपरिभाषित, सभी को पारित कर दिया जाता है:

alert(null || undefined || false || '' || 0 || 4 || 'bar'); // alerts '4'

13
''इस मामले में भी गलत मत भूलना ।
ब्रिगैंड

इंगित करने के लिए अपवोट करें f is assigned the NEAREST valueजो यहाँ एक बहुत महत्वपूर्ण बिंदु है।
स्टीवजेय

3
"निकटतम" काफी सच नहीं है, हालांकि इसमें वह उपस्थिति है। बूलियन ||ऑपरेटर, एक बूलियन ऑपरेटर होने के नाते दो ऑपरेंड हैं: एक बाईं ओर और एक दाईं ओर। तो के बाईं ओर ||है truthy , बाईं ओर और दाईं ओर आपरेशन का निराकरण नजरअंदाज कर दिया है। यदि बाईं ओर झूठा है , तो यह दाईं ओर स्थित है। तो null || undefined || 4 || 0वास्तव में हल करने के लिए undefined || 4 || 0जो हल करने के लिए 4 || 0हल करता है 4
devios1

29

इसमें कोई जादू नहीं है। बूलियन अभिव्यक्ति जैसे a || b || c || dआलसी का मूल्यांकन किया जाता है। Interpeter के मूल्य को देखता है a, यह अपरिभाषित है इसलिए यह गलत है इसलिए यह आगे बढ़ता है, फिर देखता है bकि यह अशक्त है, जो अभी भी गलत परिणाम देता है इसलिए यह आगे बढ़ता है, फिर यह देखता है c- वही कहानी। अंत में यह देखता है dऔर कहता है 'हं, यह अशक्त नहीं है, इसलिए मेरे पास मेरा परिणाम है' और यह इसे अंतिम चर पर नियत करता है।

यह ट्रिक उन सभी डायनेमिक भाषाओं में काम करेगी जो बूलियन एक्सप्रेशन का आलसी शॉर्ट-सर्किट मूल्यांकन करती हैं। स्थिर भाषाओं में यह संकलित नहीं होगा (टाइप त्रुटि)। उन भाषाओं में जो बूलियन अभिव्यक्तियों का मूल्यांकन करने में उत्सुक हैं, यह तार्किक मान लौटाएगा (अर्थात इस मामले में सच है)।


6
सुंदर स्थिर भाषा में C # एक का उपयोग कर सकते हैं ?? ऑपरेटर á la: ऑब्जेक्ट f = a b ?? सी ?? d ?? इ;
हर्जमेस्टर

2
herzmeister - धन्यवाद! मुझे नहीं पता था कि ?? ऑपरेटर को C # में जंजीर दिया जा सकता है और आलसी मूल्यांकन तकनीकों में इस्तेमाल किया जा सकता है
Marek

3
जैसा कि कहीं और उल्लेख किया गया है, उस अंतिम dको सौंपा जाएगा कि क्या यह अशक्त / अपरिभाषित था या नहीं।
BlackVegetable

एक मामूली सुधार: ||ऑपरेटर हमेशा दाईं ओर स्थित पूरे दाईं ओर स्थित होता है, जब बाईं ओर झूठा होता है। बूलियन ऑपरेटर होने के नाते यह केवल दो इनपुट देखता है: बाईं ओर और दाईं ओर। पार्सर उन्हें शर्तों की एक श्रृंखला के रूप में नहीं देखता है, इसलिए यह वास्तव में नहीं रुकता है जब यह पहला सत्य मूल्य पाता है जब तक कि मूल्य दूसरे के बाएं हाथ के ऑपरेंड भी हो ||
devios1

8

इस सवाल को पहले ही कई अच्छे जवाब मिल चुके हैं।

सारांश में, यह तकनीक इस बात का लाभ उठा रही है कि भाषा कैसे संकलित है। यही है, बूलियन ऑपरेटरों के मूल्यांकन में जावास्क्रिप्ट "शॉर्ट-सर्किट" और पहले गैर-गलत चर मूल्य या जो भी अंतिम चर होता है, से जुड़े मूल्य को वापस कर देगा। अनुराग के उन मूल्यों की व्याख्या देखें जो असत्य का मूल्यांकन करेंगे।

इस तकनीक का उपयोग करना कई कारणों से अच्छा अभ्यास नहीं है; तथापि।

  1. कोड पठनीयता: यह बूलियन ऑपरेटरों का उपयोग कर रहा है, और यदि यह संकलन कैसे समझ में नहीं आ रहा है, तो अपेक्षित परिणाम एक बूलियन मान होगा।
  2. स्थिरता: यह एक ऐसी सुविधा का उपयोग कर रहा है जिसमें भाषा को संकलित किया गया है जो कई भाषाओं में असंगत है, और इसके कारण यह कुछ ऐसा है जो संभवतः भविष्य में परिवर्तन के लिए लक्षित हो सकता है।
  3. प्रलेखित विशेषताएं: एक मौजूदा विकल्प है जो इस आवश्यकता को पूरा करता है और अधिक भाषाओं में संगत है। यह टर्नरी ऑपरेटर होगा:

    ()? मान 1: मान 2।

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

var a;
var b = null;
var c = undefined;
var d = 4;
var e = 'five';

var f =  ( a ) ? a : 
                ( b ) ? b :
                       ( c ) ? c :
                              ( d ) ? d :
                                      e;

alert(f); // 4

potentially be targeted for change in the future.हां, लेकिन मैं जावास्क्रिप्ट के लिए आवेदन नहीं करता हूं।
दादन

यहाँ आया और उपरोक्त सभी उत्तरों को देखा और अपने आप को सोच रहा था कि कुछ असाइनमेंट के बारे में अभी देखा है। मैं सिर्फ रॉबर्ट सी मार्टिन द्वारा क्लीन कोड पढ़ रहा हूं और इस प्रकार का असाइनमेंट निश्चित रूप से "कोई साइड इफेक्ट नहीं है" नियम का उल्लंघन करता है ... जबकि लेखक खुद कहता है कि उसकी किताब अच्छे कोड उत्पन्न करने के लिए कई तकनीकों में से एक है, मैं अभी भी आश्चर्य था कि किसी और ने इस तरह के असाइनमेंट पर आपत्ति नहीं जताई। +1
अल्बर्ट रोथमैन

जवाब देने के लिए धन्यवाद। मुझे लगता है कि कोड लिखते समय अधिक लोगों को साइड इफेक्ट पर विचार करने की आवश्यकता होती है, लेकिन जब तक किसी ने अन्य लोगों के कोड को बनाए रखने में बहुत समय बिताया है। वे अक्सर इस पर विचार नहीं करते हैं।
13 अक्टूबर को WSimpson

1
आप वास्तव में सोचते हैं कि राक्षसी की तुलना में स्पष्ट है a || b || c || d || e?
devios1

1
@AlbertRothman मुझे कोई साइड इफेक्ट नहीं दिखता है। कुछ भी नहीं बदला जा रहा है। यह अशक्त तालमेल के लिए एक आशुलिपि है, जो कई भाषाओं में एक बहुत ही सामान्य विशेषता है।
देवियो 1

7

आउटपुट का पहला वास्तविक मूल्य लौटाएँ ।

यदि सभी गलत हैं तो अंतिम गलत मूल्य है।

उदाहरण:-

  null || undefined || false || 0 || 'apple'  // Return apple

4

यदि यह "सत्य" (गैर-शून्य, एक वैध वस्तु / सरणी / फ़ंक्शन / जो कुछ भी है) या अन्यथा zका मान नया चर ( ) निर्धारित xकर रहा yहै। यह उस स्थिति में एक डिफ़ॉल्ट मान प्रदान करने का एक अपेक्षाकृत सामान्य तरीका है, जो xमौजूद नहीं है।

उदाहरण के लिए, यदि आपके पास एक फ़ंक्शन है जो एक वैकल्पिक कॉलबैक पैरामीटर लेता है, तो आप एक डिफ़ॉल्ट कॉलबैक प्रदान कर सकते हैं जो कुछ भी नहीं करता है:

function doSomething(data, callback) {
    callback = callback || function() {};
    // do stuff with data
    callback(); // callback will always exist
}

1

इसका अर्थ है कि यदि xसेट zकिया गया है x, yतो इसके लिए मान होगा , अन्यथा यदि सेट किया गया है, तो इसका मान सेट किया जाएगा z

यह वैसा ही है

if(x)
  z = x;
else
  z = y;

यह संभव है क्योंकि जावास्क्रिप्ट में तार्किक ऑपरेटर बूलियन मान नहीं लौटाते हैं, लेकिन ऑपरेशन को पूरा करने के लिए आवश्यक अंतिम तत्व का मूल्य (या एक वाक्य में यह पहला गैर-गलत मूल्य होगा, और एक वाक्य में यह अंतिम होगा )। यदि ऑपरेशन विफल हो जाता है, तोfalse वापस कर दिया जाता है।


5
ये गलत है! if (x) {z = x; } और {z = y;} यदि पहला मान गलत है, तो दूसरा मान हमेशा असाइन किया जाता है जो वास्तव में उस मूल्य के आधार पर नहीं होता है।
बत्तीसी

सिवाय इसके कि मुझे लगता है कि यह सिर्फ x को z को असाइन करता है अगर x गलत है । इस तरह से यह मेरे लिए एफएफ में काम करता है, बेशक, यह कार्यान्वयन पर निर्भर हो सकता है, भी।
तवानफोसन

7
असत्य को वापस करने के बारे में अंतिम भाग सत्य नहीं है (कोई दंड नहीं है)। यदि पहला मान गलत है, तो ||ऑपरेटर दूसरा मूल्य लौटाता है, भले ही वह सत्य हो या नहीं।
मैथ्यू क्रूले

-1। आपका बराबर कोड स्निपेट सही है, लेकिन महत्वपूर्ण बात यह है कि zके मान पर सेट हो जाता है x, तो यह है कि मूल्य है truthy । अन्यथा यह मूल्य पर सेट हो जाता है y। इसका मतलब है कि यदि xउदाहरण के लिए, 0या खाली स्ट्रिंग पर सेट किया गया है, ""तो यह वह नहीं करता है जो आप कहते हैं, क्योंकि वे मान गलत हैं
डैनियल कैसिडी

1

इसे शॉर्ट सर्किट ऑपरेटर कहा जाता है।

शॉर्ट-सर्किट मूल्यांकन का कहना है, दूसरे तर्क को निष्पादित या मूल्यांकन किया जाता है, अगर अभिव्यक्ति का मूल्य निर्धारित करने के लिए पहला तर्क पर्याप्त नहीं है। जब OR (||) फ़ंक्शन का पहला तर्क सत्य का मूल्यांकन करता है, तो समग्र मान सत्य होना चाहिए।

यह फ़ंक्शन तर्क के लिए एक डिफ़ॉल्ट मान सेट करने के लिए भी इस्तेमाल किया जा सकता है। `

function theSameOldFoo(name){ 
  name = name || 'Bar' ;
  console.log("My best friend's name is " + name);
}
theSameOldFoo();  // My best friend's name is Bar
theSameOldFoo('Bhaskar');  // My best friend's name is Bhaskar`

0

यह X का मूल्यांकन करेगा और, यदि X शून्य नहीं है, खाली स्ट्रिंग है, या 0 (तार्किक गलत) है, तो वह इसे z को असाइन करेगा। यदि X शून्य है, खाली स्ट्रिंग है, या 0 (तार्किक गलत) है, तो यह y से z को असाइन करेगा।

var x = '';
var y = 'bob';
var z = x || y;
alert(z);

उत्पादन करेगा 'बॉब';


आपको स्पष्ट करना चाहिए कि 'खाली' से आपका क्या मतलब है। खाली स्ट्रिंग्स के लिए मोटे हैं false, लेकिन खाली सरणियों या वस्तुओं के लिए मोटे हैं true
डैनियल कासिडी

@ डैनियल "अशक्त, रिक्त, या 0" - अशक्त सरणियों और वस्तुओं के संबंध में लागू होगा। प्वाइंट लिया, हालांकि।
तवानफोसन

0

के अनुसार विधेयक हिगिंस 'ब्लॉग पोस्ट; जावास्क्रिप्ट तार्किक या असाइनमेंट मुहावरा (फरवरी 2007), यह व्यवहार v1.2 (कम से कम) के रूप में सच है

वह इसके लिए एक और उपयोग का सुझाव भी देते हैं (उद्धृत): " क्रॉस-ब्राउज़र मतभेदों का हल्का सामान्यीकरण "

// determine upon which element a Javascript event (e) occurred
var target = /*w3c*/ e.target || /*IE*/ e.srcElement;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.