क्या करता है निर्माण x = x || आप का मतलब है?


250

मैं कुछ जावास्क्रिप्ट डिबग कर रहा हूं, और यह नहीं बता सकता कि यह क्या ||करता है?

function (title, msg) {
  var title = title || 'Error';
  var msg   = msg || 'Error on Request';
}

क्या कोई मुझे संकेत दे सकता है कि यह आदमी क्यों इस्तेमाल कर रहा है var title = title || 'ERROR'? मैं कभी-कभी इसे बिना varघोषणा के भी देखता हूं ।


44
लोगों ने पहले ही इसका उत्तर दे दिया है ... लेकिन इस तथ्य के बारे में बेहद जागरूक रहें कि दूसरा मूल्य चुना जाता है यदि पहला मूल्य falsy, केवल नहीं है undefined। जितनी बार मैंने देखा है doWeDoIt = doWeDoIt || true, मुझे रोने के लिए पर्याप्त है। (यानी doWeDoItअब कभी नहीं होगा false)
मैट


4
सी # के साथ अनुभव वाले लोगों के लिए, डबल-पाइप ऑपरेटर नल-कोलेसस ऑपरेटर के बराबर है ??। जावास्क्रिप्ट गैर-अशक्त वस्तुओं का मूल्यांकन करता है जैसे true (या बेहतर असत्य वस्तुओं को असत्य करने के लिए अशक्त)
usr-local-local

3
बुरा मत मानिए - JS इस भयानक कोडिंग की अनुमति देने वाली एकमात्र नासमझ भाषा है .... और यह सिखाते हुए कि हर फ़ंक्शन को कोड की लाइनों में घोंसला बनाना उचित है और उन्हें फेंक देना और उन्हें 2 बार डिस्पोजेबल और अनुपयोगी बना देना। :) मैं कोडिंग में 30 वर्ष का हूं और जेएस को छूने से पहले तक खुद को नहीं पकड़ पाया और मुझे लगता है कि मैं कह सकता हूं कि आपका दर्द है, "कोई मतलब नहीं है, यह केवल जेएस में है" यह केवल एक ही तरीका है। द्वारा मिल गया है! :)
कोलिन चाफिन

1
कृपया मेरे उत्तर के स्वीकृत उत्तर को बदलने पर विचार करें ।
मिचेल पेरोलाकोव्स्की

जवाबों:


211

इसका मतलब है कि titleतर्क वैकल्पिक है। इसलिए यदि आप विधि को बिना किसी तर्क के कहते हैं तो यह डिफ़ॉल्ट मान का उपयोग करेगा "Error"

यह लिखने के लिए आशुलिपि है:

if (!title) {
  title = "Error";
}

बूलियन एक्सप्रेशन के साथ इस तरह की शॉर्टहैंड ट्रिक पर्ल में भी आम है। अभिव्यक्ति के साथ:

a OR b

यह मूल्यांकन करता है करने के लिए trueकरता है, तो या तो aया bहै true। तो अगर aसच है तो आपको जाँच करने की आवश्यकता नहीं है b। इसे शॉर्ट-सर्किट बूलियन मूल्यांकन कहा जाता है:

var title = title || "Error";

मूल रूप से जाँच करता है कि क्या titleमूल्यांकन करता है false। यदि ऐसा होता है, तो यह "रिटर्न" करता है "Error", अन्यथा यह वापस आ जाता है title


3
क्षमा करें चुनने की, लेकिन तर्क वैकल्पिक नहीं है, तर्क चेक किया गया है
themightybun

4
यह जवाब नहीं है और मैं पिछली टिप्पणी से सहमत हूं यह वैकल्पिक भी नहीं है। इस उत्तर का कोई भी हिस्सा पर्ल के संदर्भ में सही नहीं है क्योंकि पर्ल स्टेटमेंट वास्तव में SENSE बनाता है और इसका मूल्यांकन पूरी तरह से किया जाता है। जेएस बहुत अधिक "परिवर्तित" बूलियन लॉजिक पद्धति में स्पष्ट है जो मुझे पढ़ने / लिखने में बहुत अधिक भ्रमित लगता है। "डबल पाइप ऑपरेटर क्या है" शीर्षक के नीचे का उत्तर वास्तव में एक सही उत्तर है।
कोलिन चाफिन

198

डबल पाइप ऑपरेटर ( ||) क्या है?

डबल पाइप ऑपरेटर ( ||) तार्किक ORऑपरेटर है । में सबसे अधिक भाषाओं यह निम्नलिखित तरीके से काम करता है:

  • यदि पहला मान है false, तो यह दूसरा मान जाँचता है। यदि यह है true, तो यह लौटता है trueऔर यदि यह है false, तो यह वापस आ जाता है false
  • यदि पहला मान है true, तो यह हमेशा लौटता है true, चाहे दूसरा मूल्य कोई भी हो।

तो मूल रूप से यह इस तरह काम करता है:

function or(x, y) {
  if (x) {
    return true;
  } else if (y) {
    return true;
  } else {
    return false;
  }
}

यदि आप अभी भी नहीं समझे हैं, तो इस तालिका को देखें:

      | true   false  
------+---------------
true  | true   true   
false | true   false  

दूसरे शब्दों में, यह केवल तभी गलत है जब दोनों मूल्य झूठे हैं।

यह जावास्क्रिप्ट में कैसे भिन्न है?

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

(function(){}) || {}

वहां क्या होता है?

यदि मान बूलियन नहीं हैं, तो जावास्क्रिप्ट बूलियन में निहित रूपांतरण बनाता है । इसका मतलब है कि अगर मूल्य falsey है (उदाहरण के लिए 0, "", null, undefined(यह भी देखें जावास्क्रिप्ट के सभी falsey मूल्यों , यह माना जाएगा)) false; अन्यथा यह माना जाता है true

तो उपरोक्त उदाहरण देना चाहिए true, क्योंकि खाली कार्य सत्य है। खैर, यह नहीं है। यह खाली फ़ंक्शन देता है। ऐसा इसलिए है क्योंकि जावास्क्रिप्ट ||ऑपरेटर काम नहीं करता है जैसा कि मैंने शुरुआत में लिखा था। यह निम्नलिखित तरीके से काम करता है:

  • यदि पहला मान गलत है , तो यह दूसरा मान लौटाता है
  • यदि पहला मान सत्य है , तो यह पहला मान लौटाता है

आश्चर्य चकित? वास्तव में, यह पारंपरिक ||ऑपरेटर के साथ "संगत" है । यह निम्नलिखित समारोह के रूप में लिखा जा सकता है:

function or(x, y) {
  if (x) {
    return x;
  } else {
    return y;
  }
}

यदि आप एक सत्य मान को पास करते हैं x, तो यह लौटाता है x, अर्थात एक सत्य मूल्य। इसलिए यदि आप इसे बाद में ifखंड में उपयोग करते हैं :

(function(x, y) {
  var eitherXorY = x || y;
  if (eitherXorY) {
    console.log("Either x or y is truthy.");
  } else {
    console.log("Neither x nor y is truthy");
  }
}(true/*, undefined*/));

आपको मिलता है "Either x or y is truthy."

अगर xझूठी होती, eitherXorYहोती y। इस मामले में आप "Either x or y is truthy."अगर yसच होता; अन्यथा आप प्राप्त करेंगे "Neither x nor y is truthy"

वास्तविक सवाल

अब, जब आप जानते हैं कि ||ऑपरेटर कैसे काम करता है, तो आप संभवतः अपने आप से बाहर कर सकते हैं कि x = x || yइसका क्या मतलब है। यदि xसत्य है, xको सौंपा गया है x, तो वास्तव में कुछ भी नहीं होता है; अन्यथा yसौंपा गया है x। यह आमतौर पर कार्यों में डिफ़ॉल्ट मापदंडों को परिभाषित करने के लिए उपयोग किया जाता है। हालांकि, इसे अक्सर एक बुरा प्रोग्रामिंग अभ्यास माना जाता है , क्योंकि यह आपको एक पैरामीटर के रूप में एक गलत मूल्य (जो जरूरी नहीं है undefinedया null) पारित करने से रोकता है । निम्नलिखित उदाहरण पर विचार करें:

function badFunction(/* boolean */flagA) {
  flagA = flagA || true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

यह पहली नजर में वैध लगता है। हालाँकि, अगर आप पैरामीटर के falseरूप में पास हुए हैं तो क्या होगा flagA(चूंकि यह बूलियन है, यानी हो सकता है trueया false)? यह बन जाएगा trueइस उदाहरण में, सेट flagAकरने का कोई तरीका नहीं है false

यह स्पष्ट रूप से जांचना बेहतर होगा कि क्या flagAहै undefined, जैसे:

function goodFunction(/* boolean */flagA) {
  flagA = typeof flagA !== "undefined" ? flagA : true;
  console.log("flagA is set to " + (flagA ? "true" : "false"));
}

हालांकि यह लंबा है, यह हमेशा काम करता है और इसे समझना आसान है।


आप डिफ़ॉल्ट फ़ंक्शन मापदंडों के लिए ES6 सिंटैक्स का भी उपयोग कर सकते हैं , लेकिन ध्यान दें कि यह पुराने ब्राउज़रों (जैसे IE) में काम नहीं करता है। आप इन ब्राउज़र का समर्थन करना चाहते हैं, तो आप के साथ अपने कोड transpile चाहिए कोलाहल

एमडीएन पर लॉजिकल ऑपरेटर्स भी देखें ।


13
+1 - अब तक का सबसे सही और पूर्ण उत्तर। और, इस सवाल के साथ उन लोगों के लिए (जिनमें से कुछ जेएस शामिल करने के लिए नए अनुभवी) निश्चित रूप से इस लाइन पर इस पूरे जवाब से सबसे अधिक ध्यान केंद्रित करना चाहिए: "हालांकि यह कोई मतलब नहीं है" क्योंकि यह "लूसली टाइप" बस कभी मतलब नहीं होगा हम में से जो इसके बिना बड़े हुए। हमारे लिए, एक बूलियन ऑपरेटर सिर्फ और सिर्फ यह है कि ...... और जिसे कभी भी लगा कि उसे पढ़ना / लिखना कोड करते समय गैर-बूलियन मूल्यों के कुछ निराला रूपांतरणों के माध्यम से रोकना और सोचना अच्छा होगा। , उस दिन उनका ध्यान रखना भूल गया! :)
कोलिन चाफिन

2
+1, संक्षेप में: का title = title || 'Error'अर्थ हैif (title) { title = title; } else { title = 'Error'; }
आंद्रे एलरिको

मैं वास्तव में "हालांकि इससे कोई मतलब नहीं है" से सहमत नहीं हूं। मैं समझता हूं कि लाइन सी में संकलित नहीं होगी, उदाहरण के लिए, लेकिन यह अच्छी तरह से समझा जाता है यदि आप उदाहरण के लिए रूबी से आए हैं, या यहां तक ​​कि ग्रूवी भी। रूबी में आप इसे और भी छोटे रूप में व्यक्त कर सकते हैं title ||= 'Error'
इलियट नेल्सन

28

यदि शीर्षक सेट नहीं है, तो डिफ़ॉल्ट मान के रूप में 'ERROR' का उपयोग करें।

अधिक सामान्य:

var foobar = foo || default;

पढ़ता है: फोमोबार को fooया पर सेट करें default। आप इसे कई बार चेन कर सकते हैं:

var foobar = foo || bar || something || 42;

1
मुझे यह भ्रामक लगा, क्योंकि चर का एक ही नाम है। बहुत आसान है जब वे नहीं करते हैं।
नोर्बर्ट नोबर्टनसन

14

इसे थोड़ा और समझाते हुए ...

||ऑपरेटर तार्किक है orऑपरेटर। परिणाम सत्य है यदि पहला भाग सत्य है और यह सत्य है यदि दूसरा भाग सत्य है और यह सत्य है यदि दोनों भाग सत्य हैं। स्पष्टता के लिए, यहाँ यह एक तालिका में है:

 X | Y | X || Y 
---+---+--------
 F | F |   F    
---+---+--------
 F | T |   T    
---+---+--------
 T | F |   T    
---+---+--------
 T | T |   T    
---+---+--------

अब यहाँ कुछ नोटिस? यदि Xसत्य है, तो परिणाम हमेशा सत्य होता है। इसलिए अगर हम जानते हैं कि Xयह सच है तो हमें जांचने की जरूरत नहीं है Y। कई भाषाएं तार्किक or(और तार्किक- andदूसरी दिशा से आने वाली) के लिए "शॉर्ट सर्किट" मूल्यांकनकर्ताओं को लागू करती हैं । वे पहले तत्व की जांच करते हैं और अगर यह सच है तो वे दूसरे की जांच करने से परेशान नहीं होते हैं। परिणाम (तार्किक शब्दों में) समान है, लेकिन निष्पादन के मामले में संभावित रूप से एक बड़ा अंतर है यदि दूसरा तत्व गणना करने के लिए महंगा है।

तो इसका आपके उदाहरण से क्या लेना-देना है?

var title   = title || 'Error';

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

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


8

डबल पाइप तार्किक "या" के लिए खड़ा है। यह वास्तव में ऐसा नहीं है जब "पैरामीटर सेट न हो", कड़ाई से जावास्क्रिप्ट में अगर आपके पास इस तरह का कोड है:

function foo(par) {
}

फिर कॉल करता है

foo()
foo("")
foo(null)
foo(undefined)
foo(0)

समतुल्य नहीं हैं।

डबल पाइप (||) बूलियन को पहला तर्क देगा और यदि परिणामस्वरूप बूलियन सही है - असाइनमेंट करें अन्यथा यह सही भाग असाइन करेगा।

यह तब होता है जब आप अनसेट पैरामीटर के लिए जाँच करते हैं।

मान लीजिए कि, हमारे पास एक फ़ंक्शन सेटरीरी है जिसमें एक वैकल्पिक पैरामीटर है। यदि उपयोगकर्ता पैरामीटर की आपूर्ति नहीं करता है, तो 10 के डिफ़ॉल्ट मान का उपयोग किया जाना चाहिए।

यदि आप इस तरह से जाँच करते हैं:

function setSalary(dollars) {
    salary = dollars || 10
}

यह कॉल की तरह अप्रत्याशित परिणाम देगा

setSalary(0) 

यह अभी भी ऊपर वर्णित प्रवाह के बाद 10 सेट करेगा।


8

मूल रूप से यह जाँचता है कि क्या मूल्य से पहले || सत्य का मूल्यांकन, यदि हाँ, तो यह मान लेता है, यदि नहीं, तो यह मान लेता है ||

मान जिसके लिए यह मान लेगा || (जहां तक ​​मुझे याद है):

  • अपरिभाषित
  • असत्य
  • 0
  • '' (अशक्त या अशक्त)

1
झूठा || अशक्त || अपरिभाषित || 0 || '' || 'आप भूल गए'
Dziamid

7

जब भी क्लेटस का उत्तर सही होता है, मुझे लगता है कि जावास्क्रिप्ट में "गलत का मूल्यांकन" करने के संबंध में अधिक विवरण जोड़ा जाना चाहिए।

var title = title || 'Error';
var msg   = msg || 'Error on Request';

क्या केवल जाँच नहीं है कि क्या शीर्षक / संदेश प्रदान किया गया है, बल्कि यदि उनमें से कोई भी गलत है । निम्नलिखित में से एक:

  • असत्य।
  • 0 (शून्य)
  • "" (खाली स्ट्रिंग)
  • शून्य।
  • अपरिभाषित।
  • NaN (एक विशेष संख्या मान जिसका अर्थ संख्या-ए-नंबर नहीं है!)

तो लाइन में

var title = title || 'Error';

यदि शीर्षक सत्य है (अर्थात, मिथ्या नहीं है, इसलिए शीर्षक = "टाइटलमेसज" आदि) तो Beanean OR (()) ऑपरेटर को एक 'सही' मान मिला है, जिसका अर्थ है कि यह सत्य का मूल्यांकन करता है, इसलिए यह शॉर्ट-सर्किट और रिटर्न सही मूल्य (शीर्षक)।

यदि शीर्षक गलत है (यानी ऊपर दी गई सूची में से एक), तो बुलियन OR (()) ऑपरेटर को 'गलत' मान मिला है, और अब ऑपरेटर के दूसरे भाग, 'त्रुटि' का मूल्यांकन करने की आवश्यकता है, जो सही का मूल्यांकन करता है , और इसलिए लौटा है।

यह भी प्रतीत होता है (कुछ त्वरित फायरबग कंसोल प्रयोग के बाद) यदि ऑपरेटर के दोनों पक्ष झूठे का मूल्यांकन करते हैं, तो यह दूसरा 'झूठा' ऑपरेटर देता है।

अर्थात

return ("" || undefined)

अनिर्धारित रिटर्न, यह संभवतः आपको इस सवाल के बारे में पूछे गए व्यवहार का उपयोग करने की अनुमति देता है जब "" के लिए डिफ़ॉल्ट शीर्षक / संदेश की कोशिश कर रहा हो। यानी दौड़ने के बाद

var foo = undefined
foo = foo || ""

foo "" पर सेट हो जाएगा


5

डबल पाइप ऑपरेटर

क्या यह उदाहरण उपयोगी है?

var section = document.getElementById('special');
if(!section){
     section = document.getElementById('main');
}

भी हो सकते हैं

var section = document.getElementById('special') || document.getElementById('main');

4

मेरे सामने सभी के लिए कुछ स्पष्टीकरण जोड़ने के लिए, मुझे आपको तार्किक अवधारणाओं को समझने के लिए कुछ उदाहरण देने चाहिए।

var name = false || "Mohsen"; # name equals to Mohsen
var family = true || "Alizadeh" # family equals to true

इसका अर्थ है कि यदि बाईं ओर का मूल्यांकन एक सच्चे कथन के रूप में किया गया है तो इसे समाप्त कर दिया जाएगा और बाईं ओर वापस लौटा दिया जाएगा और चर को सौंपा जाएगा। अन्य मामलों में सही पक्ष को वापस लौटाया और सौंपा जाएगा।

और ऑपरेटर नीचे की तरह विपरीत संरचना है।

var name = false && "Mohsen" # name equals to false
var family = true && "Alizadeh" # family equals to Alizadeh

3

|| बूलियन या ऑपरेटर है। जावास्क्रिप्ट में के रूप में, अपरिभाषित, अशक्त, 0, झूठी माना जाता है falsy मूल्यों।

इसका सीधा सा मतलब है

true || true = true
false || true = true
true || false = true
false || false = false

undefined || "value" = "value"
"value" || undefined = "value"
null || "value" = "value"
"value" || null = "value"
0 || "value" = "value"
"value" || 0 = "value"
false || "value" = "value"
"value" || false = "value"

2

Quote: "क्या निर्माण x = x || y का मतलब है?"

डिफ़ॉल्ट मान असाइन करना।

इसका मतलब यह है कि यदि x अभी भी अपने मूल्य की प्रतीक्षा कर रहा है, लेकिन अभी तक इसे प्राप्त नहीं किया गया है या डिफ़ॉल्ट रूप से वापस गिरने के लिए इसे जानबूझकर छोड़ा नहीं गया है, तो y से x का डिफ़ॉल्ट मान प्रदान करता है


यह निर्माण का सटीक अर्थ है और इसका एकमात्र अर्थ है। और यह मोटे तौर पर लेखन कार्यों में एक सबरूटीन के रूप में था जिसे प्रोटोटाइप, स्टैंडअलोन फ़ंक्शन के रूप में प्राप्त किया जा सकता था, और दूसरे तत्व पर लागू होने के लिए उधार के तरीकों के रूप में भी। जहां इसका मुख्य और एकमात्र कर्तव्य लक्ष्य के संदर्भ को संशोधित करना था। उदाहरण: function getKeys(x) { x = x || this ; .... }जो एक स्टैंडअलोन समारोह के रूप में संशोधन के बिना इस्तेमाल किया जा सकता, प्रोटोटाइप में एक संपत्ति विधि के रूप में और एक तत्व के रूप में एक तरीका है जिसके `[तत्व] .getKeys (anotherElement) ने अपने तर्क के रूप में एक और तत्व प्राप्त कर सकते हैं के रूप में,`
Bekim Bacaj

-5

और मुझे एक और बात जोड़नी होगी: यह थोड़ा आशुलिपि एक घृणा है। यह एक आकस्मिक दुभाषिया अनुकूलन का दुरुपयोग करता है (असाइनमेंट नियंत्रित करने के लिए यदि पहला सच है तो दूसरे ऑपरेशन से परेशान नहीं)। उस उपयोग का ऑपरेटर के उद्देश्य से कोई लेना-देना नहीं है। मेरा मानना ​​है कि इसका कभी भी इस्तेमाल नहीं किया जाना चाहिए।

मैं इनिशियलाइज़ेशन के लिए टर्नरी ऑपरेटर को पसंद करता हूँ, जैसे,

var title = title?title:'Error';

यह अपने सही उद्देश्य के लिए एक-लाइन सशर्त संचालन का उपयोग करता है। यह अभी भी सच्चाई के साथ भद्दा खेल खेलता है लेकिन, यह आपके लिए जावास्क्रिप्ट है।

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