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


376

मेरे पास यह कोड है ( इस प्रश्न से लिया गया है ):

var walk = function(dir, done) {
    var results = [];

    fs.readdir(dir, function(err, list) {
        if (err)
            return done(err);

        var pending = list.length;

        if (!pending) 
            return done(null, results);

        list.forEach(function(file) {
            file = path.resolve(dir, file);
            fs.stat(file, function(err, stat) {
                if (stat && stat.isDirectory()) {
                    walk(file, function(err, res) {
                        results = results.concat(res);

                        if (!--pending)
                            done(null, results);
                    });
                } else {
                    results.push(file);

                    if (!--pending) 
                        done(null, results);
                }
            });
        });
    });
};

मैं इसका पालन करने की कोशिश कर रहा हूं, और मुझे लगता है कि मैं अंत के पास के अलावा सब कुछ समझता हूं जहां यह कहता है !--pending। इस संदर्भ में, वह आदेश क्या करता है?

संपादित करें: मैं सभी आगे की टिप्पणियों की सराहना करता हूं, लेकिन सवाल का जवाब कई बार दिया गया है। फिर भी धन्यवाद!


222
यह कोड को बनाए रखने के लिए अगले व्यक्ति को भ्रमित करने का एक शानदार तरीका है।
एरिक जे।

240
!~--[value] ^ trueमैं इस "नौकरी की सुरक्षा" जैसे कोड को कॉल करता हूं
TbWill4321


36
@ TbWill4321 अगर मैं कोड की समीक्षा कर रहा था, तो यह नौकरी की सुरक्षा के बिल्कुल विपरीत होगा।
corsiKa

8
परिवर्तनीय नाम के साथ संयुक्त ऑपरेटर बहुत बुरा नहीं है। किसी भी अनुभवी जावास्क्रिप्ट प्रोग्रामर को यह जानने के लिए कुछ सेकंड से अधिक की आवश्यकता नहीं होगी।
क्रिस्टियान वेस्टरबेक

जवाबों:


537

! एक मूल्य प्राप्त करता है, और आपको विपरीत बूलियन देता है:

!true == false
!false == true
!1 == false
!0 == true

--[value] एक नंबर से एक (1) घटाते हैं, और फिर उस नंबर के साथ काम किया जाता है:

var a = 1, b = 2;
--a == 0
--b == 1

इसलिए, !--pendingकिसी को लंबित से घटाकर, और फिर उसके सत्य / झूठे मूल्य (चाहे वह हो या नहीं 0) के विपरीत लौटाता है ।

pending = 2; !--pending == false 
pending = 1; !--pending == true
pending = 0; !--pending == false

और हाँ, ProTip का पालन करें। यह अन्य प्रोग्रामिंग भाषाओं में एक सामान्य मुहावरा हो सकता है, लेकिन अधिकांश घोषित जावास्क्रिप्ट प्रोग्रामिंग के लिए यह काफी अलग दिखता है।


623
ProTip ™: कभी भी अपने कोड में ऐसा न करें, यह हास्यास्पद है।
नातुल्ली काई

17
यह उल्लेख नहीं करता है कि --केवल चर पर कार्य करता है; आप इसे सामान्य रूप से मानों पर लागू नहीं कर सकते।
डेल्टैब

10
@ डैल्टैब: validSimpleAssignmentTargetएस, सटीक होना। इसमें पहचानकर्ता संदर्भ और संपत्ति संदर्भ शामिल हैं।
बरगी

19
--0और --1काम नहीं करेगा। संख्यात्मक शाब्दिक मान्य बाएं हाथ की अभिव्यक्ति नहीं हैं
PSWai

7
@ चित्र: उह, मुझे उस i > -1चीज़ को पार्स करने में अधिक परेशानी है i--(और आपको भूल गए i = init() - 1)। यही मुहावरे हैं ... और हर प्रोग्रामर को उन्हें सीखना चाहिए।
बर्गी १

149

यह एक विशेष ऑपरेटर नहीं है, यह एक के बाद एक 2 मानक ऑपरेटर है:

  1. एक उपसर्ग घटाना ( --)
  2. एक तार्किक नहीं ( !)

यह pendingघटने का कारण बनता है और फिर यह देखने के लिए परीक्षण किया जाता है कि क्या यह शून्य है।


8
मैं निश्चित रूप से इस के लिए नया हूँ, लेकिन यह उपयोग करने के लिए बेहतर क्यों है if(pending === 1)?
कीरन E

46
@ कीरेन, यह नहीं है, यह आशुलिपि है जो "पठनीयता राजा है" के नियम को पूरी तरह से तोड़ देती है।
22

23
@ कीरन यह श्रेष्ठ होने के बारे में नहीं है, यह अलग है। यह वेरिएबल को म्यूट करता है (इसे 1 से घटाता है) और फिर परीक्षण के लिए नए मान का उपयोग करता है
अमित

7
@ कीरेन, यह बराबर है if( pending === 1 ) { done... } else { pending = pending - 1; }
कंप्युटरशिप

7
@CompuChip वास्तव में ऐसा लगता है - किसी भी मामले में लंबित किया जाएगा, इसलिए कोड अधिक है: यदि (लंबित) {--pending; आदि} और {--pending; आदि} यह developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
पॉल रसेल

109

कई उत्तर बताते हैं कि यह कमांड क्या करता है, लेकिन यहां ऐसा क्यों नहीं किया गया।

मैं सी दुनिया से आता हूं, और मैं इसके बारे में वास्तव में सोचने के बिना !--pending"गिनना pendingऔर जांचें कि क्या यह शून्य है" के रूप में पढ़ा जाता है। यह एक मुहावरा है कि मुझे लगता है कि समान भाषाओं में प्रोग्रामर को पता होना चाहिए।

फ़ंक्शन readdirफ़ाइलों और उपनिर्देशिकाओं की एक सूची प्राप्त करने के लिए उपयोग करता है, जिसे मैं सामूहिक रूप से "प्रविष्टियां" कहूंगा।

चर इस pendingपर नज़र रखता है कि इनमें से कितने को संसाधित किया जाना बाकी है। यह सूची की लंबाई के रूप में शुरू होता है, और प्रत्येक प्रविष्टि के संसाधित होते ही शून्य की ओर नीचे की ओर गिना जाता है।

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

के साथ पहली कॉल doneमें प्रीपेन्डेड है return, इसलिए नहीं कि हम एक वैल्यू लौटाना चाहते हैं, लेकिन बस उस बिंदु पर फंक्शन को अंजाम देना बंद कर दें। यह एक ड्रॉप करने के लिए क्लीनर कोड होता returnऔर विकल्प को एक में डाल दिया जाता else


13
@ बर्गी सी दुनिया का एक जाना-माना मुहावरा है, लेकिन यह मुहावरेदार नहीं है। किसी भी उपसमुच्चय के लिए, अलग-अलग पारिस्थितिक तंत्रों में विभिन्न, असंगत मुहावरों की विविधता होगी, वहां 'यह कैसे किया जाता है'। 'विदेशी' भाषाओं से मुहावरों का उपयोग करना एक बुरी कोड गंध है।
पीटरिस

3
@Peteris: यह सभी सी-लाइक भाषाओं में एक मुहावरा है जिसमें डिक्रीमेंट ऑपरेटर होता है। बेशक, कभी-कभी एक भाषा में अलग, बेहतर तरीके उपलब्ध होते हैं, लेकिन मुझे नहीं लगता कि जेएस की कोई विशेष गिनती मुहावरे हैं।
बरगी

6
जावास्क्रिप्ट समुदाय का एक महत्वपूर्ण हिस्सा है, जिसमें डगलस क्रॉकफोर्ड जैसे प्रभावशाली नेता शामिल हैं, जो पूरी तरह से वेतन वृद्धि और वेतन वृद्धि ऑपरेटरों से बचने की वकालत करते हैं । मैं यहां इस बारे में बहस नहीं करने जा रहा हूं कि वे सही हैं या नहीं; मेरा इरादा केवल यह !--pendingबताना है कि क्योंकि विवाद मौजूद है, जैसे कोड कई लिंटर और स्टाइल दिशानिर्देशों को विफल कर देगा। मेरे लिए यह कहने के लिए पर्याप्त है कि यह शायद मुहावरेदार नहीं है (परवाह किए बिना कि विकल्प "बेहतर" है)।
ग्रैंडऑपनर

3
@GrandOpener "मुहावरेदार" का अर्थ है "देशी वक्ताओं द्वारा समझी जाने वाली अभिव्यक्ति"। पूर्वनिर्धारण निश्चित रूप से सी जैसी भाषाओं के उपयोगकर्ताओं के लिए अच्छी तरह से समझा जाता है और, विस्तार से, इसलिए "! (- x)" है। किसी चीज़ का उपयोग करना या न करना एक अच्छा विचार है। यह एक अलग सवाल है कि यह कितना मुहावरेदार है। (उदा। मुझे अत्यधिक संदेह है कि आप किसी भी भाषा के कई प्रोग्रामर में भाग लेंगे जो यह नहीं समझते हैं कि "गोटो" क्या करता है, अक्सर व्यक्त की गई राय के बावजूद कि आपके कोड में यह सूची में "वासना" और "मर्डर" के बीच में आता है। आठ घातक पापों के कारण।)
जुंबियानो

3
@Pharap की वजह से सी # और जावा न करने वाली यही कारण है कि intकरने के लिए boolपरोक्ष, और कुछ नहीं के उपयोग से संबंधित है !--
अगोप

36

यह एक आशुलिपि है।

! नहीं है"।

-- मूल्य घटाता है।

इसलिए !--जांचता है कि मूल्य में गिरावट के परिणाम को नकारने से प्राप्त मूल्य गलत है या नहीं।

इसे इस्तेमाल करे:

var x = 2;
console.log(!--x);
console.log(!--x);

पहला गलत है, क्योंकि x का मान 1 है, दूसरा सच है, क्योंकि x का मान 0 है।

साइड नोट: !x--जाँच करेगा कि क्या x पहले गलत है, और फिर इसे घटाया जाए।


आरई नोट ध्यान दें - क्या आप सुनिश्चित हैं? ऐसा लगता है कि पोस्ट-फिक्स की तुलना में अधिक पूर्वता है !, जबकि पूर्व-फिक्स में कम पूर्वता है। जावास्क्रिप्ट संचालक पूर्वता
Dannnno

2
हाँ। (कोशिश var x = 2; console.log(!x--); console.log(!x--); console.log(!x--);)। हालांकि पोस्ट-फिक्स --पहले निष्पादित हो सकता है, इसका रिटर्न वैल्यू डिक्रिमेंटिंग से पहले वेरिएबल का मूल्य है ( Decrement Opperator )।
लुकास

मुझे लगता है कि आपके कहने का मतलब है " !--मूल्य में कमी के परिणाम की उपेक्षा लौटाता है।" केवल बाहर का कोड, जैसे कि console.log(), जाँचता है कि क्या इसकी सामग्री सत्य है।
मढ़ौरा

31

!जावास्क्रिप्ट संचालक नहीं है

--एक प्री-डेक्रिमेंट ऑपरेटर है। इसलिए,

x = 1;
if (!x) // false
if (!--x) // becomes 0 and then uses the NOT operator,
          // which makes the condition to be true

8
WTH एक "झूठा कथन" है?
बरगी

5
@Bergi मुझे लगता है कि आप वास्तव में जानते हैं कि इसका क्या मतलब है, लेकिन अगर आप (या किसी और को नहीं) यहाँ जावास्क्रिप्ट के लिए एक स्पष्टीकरण है जो इस अवधारणा (जैसे पायथन) के साथ कुछ अन्य भाषाओं में भी अच्छी तरह से अनुवाद करता है।
दन्ननो

1
@ यह मेरा जवाब नहीं है, इसलिए मैं इसे छूने नहीं जा रहा हूं।
दन्ननो

2
@Dannnno: ठीक है मुझे पता है कि falsy मान रहे हैं और क्या बयान है, और इसलिए मैं जानता हूँ कि एक "falsy बयान" जे एस में की तरह ऐसी कोई बात नहीं है। मुझे लगता है कि यह तर्क शब्द का उल्लेख नहीं करता है ।
बर्गी १

1
मुझे समझ नहीं आ रहा है कि कैसे -- ऑपरेटर एक निरंतर के साथ काम कर सकता है ... शायद आप के --xबजाय इसका मतलब है --0?
SJuan76

24
if(!--pending)

माध्यम

if(0 == --pending)

माध्यम

pending = pending - 1;
if(0 == pending)

4
और यह कोड लिखने का स्पष्ट तरीका है। बेशक, मैं if(0 == pending)टाइपो की क्षमता के कारण पसंद करता हूं । if(0 = pending)एक वाक्यविन्यास त्रुटि है। if(pending = 0)एक असाइनमेंट है जो तैयार कोड में भ्रामक व्यवहार का कारण होगा।
थियो ब्रिंकमैन

3
@ TheoBrinkman: वास्तव if(0 = pending)में एक वाक्यविन्यास त्रुटि नहीं है - यह ठीक है - लेकिन एक संदर्भ त्रुटि क्योंकि 0असाइन करने योग्य नहीं है (रेफरी ECMA-262 (6 वें संस्करण) सेकंड 12.14.1)।
हमखोलम ने मोनिका डेस

13

यह इन-प्लेस प्री-डिक्रीमर के बाद का ऑपरेटर नहीं है।

तो अगर pending1 के मान के साथ पूर्णांक था:

val = 1;
--val; // val is 0 here
!val // evaluates to true

11

यह केवल pendingएक से घटता है और अपने तार्किक पूरक (निषेध) को प्राप्त करता है। किसी भी संख्या का तार्किक पूरक 0 से भिन्न है false, 0 के लिए है true


कृपया ध्यान दें कि "नेगेट" का
बूलियनों की

1
ठीक है, मैं एक अलग शब्द का उपयोग करूँगा। यकीन नहीं होता कि यह बेहतर है।
माइनसफॉर

11

व्याख्या

यह 2 ऑपरेटरों, एक !और एक है--

!--x 

तो, --1 से एक्सरे घटते हैं, फिर! रिटर्न सही है यदि x अब 0 (या NaN ...) है, तो गलत है यदि यह नहीं है। आप इस मुहावरे को कुछ इस तरह पढ़ सकते हैं, जैसे "हम एक्स को घटाते हैं और अगर यह शून्य हो जाता है ..."

यदि आप इसे और अधिक पठनीय बनाना चाहते हैं, तो आप यह कर सकते हैं:

var x = 1
x = x - 1   
if(!x){ //=> true
    console.log("I understand `!--` now!") 
}
x //=> 0

कोशिश करके देखो:

/* This is an example of the above, you can read this, but it is not needed for !-- */function interactive(a){$("span.code").keydown(function(e){if(13==(e.keyCode||e.which)){var t=$(this);t.clone().html("code").insertAfter(t.next().next()).show().focus().after(template.clone().removeClass("result-template").show()).next().after("<br>"),interactive(),e.preventDefault()}}).keyup(function(e){13!=(e.keyCode||e.which)&&run()})}var template=$(".result-template").hide(),code=$("span.code");code.attr("contenteditable","true").each(function(e,t){template.clone().removeClass("result-template").insertAfter(t)}),interactive(),$.fn.reduce=[].reduce;function run(){var b=!1,context={};$("span.code").each(function(){var a=$(this),res=a.next().show().removeClass("error");try{with(context)res.html(b?"":"  //=> "+eval(a.text()))}catch(e){b=e,res.html("  Error: "+b.message).addClass("error")}})};run();
/* This is an example of the above, you can read this, but it is not needed for !-- */span.result.error{display:block;color:red}.code{min-width:10px}body{font-family:Helvetica,sans-serif}
<!-- This is an example of the above, you can read this, but it is not needed for `!--` --><span class="result result-template"> //=> unknown </span> <h2>Edit This Code:</h2><code><span class="code">x = 1</span><br><span class="code">!--x</span><br><span class="code"> x </span><br></code> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

फिडेल (कोड से बाहर की कोशिश करें)


8

यहाँ वास्तविक समस्या दो ऑपरेटरों के बीच एक जगह की कमी है !और --

मुझे नहीं पता कि लोगों के सिर में यह क्यों है कि आप कभी भी एक स्थान का उपयोग नहीं कर सकते हैं ! ऑपरेटर के । मुझे लगता है कि यह सामान्य ज्ञान के बजाय यांत्रिक व्हाट्सएप नियमों के कठोर अनुप्रयोग से आता है। बस हर कोडिंग मानक के बारे में मैंने देखा है कि सभी यूनिरी ऑपरेटरों के बाद रिक्त स्थान पर प्रतिबंध है, लेकिन क्यों?

अगर कभी कोई ऐसा मामला सामने आया जहां आपको स्पष्ट रूप से जरूरत है उस स्थान की है, तो यह एक है।

इस कोड पर विचार करें:

if (!--pending)
    done(null, results);

न केवल एक साथ !और --मैश किए हुए हैं, आपको वह मिल गया है( उनके खिलाफ भी पटक दिया है। कोई आश्चर्य नहीं कि यह बताना मुश्किल है कि क्या जुड़ा है।

थोड़ा अधिक व्हाट्सएप कोड को और अधिक स्पष्ट करता है:

if( ! --pending )
    done( null, results );

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

लेकिन यह देखिए कि अतिरिक्त व्हाट्सएप समूह कैसे ifबयान और अभिव्यक्ति के विभिन्न हिस्सों को अलग करता है : आपको मिल गया है --pending, इसलिए --यह स्पष्ट रूप से अपना स्वयं का ऑपरेटर है और निकट से जुड़ा हुआ है pending। (यह घटता है pendingऔर घटा हुआ परिणाम लौटाता है।) फिर आप इससे !अलग हो गए हैं, इसलिए यह स्पष्ट रूप से एक अलग ऑपरेटर है, परिणाम को नकार रहा है। अंत में, आप मिल गया है if(और )पूरे अभिव्यक्ति आसपास यह एक बनाने के लिए ifबयान।

और हाँ, मैं के बीच की जगह से हटाया ifऔर (, क्योंकि ( अंतर्गत आता है करने के लिए if। यह (किसी प्रकार के (!--सिंटैक्स का हिस्सा नहीं है क्योंकि यह मूल में प्रतीत होता है, (यदि ifकथन के सिंटैक्स का हिस्सा ।

यहाँ व्हॉट्सएप कुछ यांत्रिक कोडिंग मानक का पालन करने के बजाय अर्थ को संप्रेषित करने का कार्य करता है ।


1
व्हाट्सएप संस्करण मेरे लिए अधिक पठनीय है। जब मैंने पहली बार प्रश्न देखा तो मुझे लगा कि !--कुछ जावास्क्रिप्ट ऑपरेटर है जो मुझे नहीं पता था। इसे और भी अधिक स्पष्ट करने के लिए कोष्ठक का उपयोग क्यों नहीं करते? if(!(--pending))
एमोरी

1
कोई शैली गाइड नहीं है जिसका मैं उपयोग करने से मना कर रहा हूँ ++या --, लेकिन कई उपसर्ग ऑपरेटर और गैर-आवश्यक कोष्ठक के बाद गैर-आवश्यक रिक्त स्थान का उपयोग करने से रोकते हैं !

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