"नए" ऑपरेटर का उपयोग करके ऑब्जेक्ट बनाते समय हम कोष्ठक को छोड़ सकते हैं?


229

मैंने वस्तुओं को इस तरह से बनते देखा है:

const obj = new Foo;

लेकिन मुझे लगा कि ऑब्जेक्ट बनाते समय कोष्ठक वैकल्पिक नहीं हैं:

const obj = new Foo();

क्या ECMAScript मानक में वस्तुओं को वैध और परिभाषित करने का पूर्व तरीका है? क्या वस्तुओं को बनाने के पूर्व तरीके और बाद में कोई मतभेद हैं? क्या एक को दूसरे पर पसंद किया जाता है?



अद्यतन संदर्भ: ECMAScript 2017 §12.3.3 नया ऑपरेटर
RobG

टी एल; डॉ: खबरदार कि new a.b()से अलग है new a().b()कि में, पूर्व मामले में, a.bपहले से पहुंचा जाता है, जबकि दूसरे मामले में, एक नया aपहले बनाई गई है।
एंड्रयू

जवाबों:


238

डेविड फ्लानगन का उद्धरण 1 :

एक विशेष मामले के रूप में, newकेवल ऑपरेटर के लिए , जावास्क्रिप्ट फ़ंक्शन को कॉल में कोई तर्क नहीं होने पर लघुकोष्ठक को छोड़ने की अनुमति देकर व्याकरण को सरल बनाता है। newऑपरेटर के उपयोग के कुछ उदाहरण इस प्रकार हैं :

o = new Object;  // Optional parenthesis omitted here
d = new Date();  

...

व्यक्तिगत रूप से, मैं हमेशा कोष्ठक का उपयोग करता हूं, तब भी जब निर्माता कोई तर्क नहीं लेता है।

इसके अलावा, यदि आप कोष्ठक को छोड़ देते हैं तो JSLint आपकी भावनाओं को आहत कर सकता है। यह रिपोर्ट Missing '()' invoking a constructorकरता है, और कोष्ठक की चूक को सहन करने के लिए उपकरण का विकल्प नहीं लगता है।


1 डेविड फ्लैनगन: जावास्क्रिप्ट द डेफिनिटिव गाइड: 4th एडिशन (पेज 75)


6
जेएसएलआईएन कोष्ठक के उपयोग को प्रोत्साहित क्यों करता है?
Randomblue

11
मुझे लगता है कि यह सिर्फ अधिक सुसंगत माना जाता है।
डैनियल वैसलो

12
मैं यह है कि कई JavaScript डेवलपर कोष्ठक का उपयोग देखने के लिए बस क्योंकि "उपकरण (JSLint) ऐसा करने के लिए उन से कहा" दिलचस्प है, खासकर यह देखते हुए कि पर उदाहरण developer.mozilla.org/en-US/docs/Web/JavaScript/Guide / ... , "उन लोगों से जिन्होंने <expletive> भाषा का आविष्कार किया" new Classपैरामीटर रहित बिल्डरों के लिए किसी भी कोष्ठक का उपयोग नहीं करते हैं । अगर यह 'राय' नहीं देता है, तो मुझे नहीं पता कि क्या करता है ...
ack

52
@ack खैर, यह अजीब होगा नहीं देखने के लिए भाषा का अन्वेषकों उनकी भाषा की कुछ सुविधाओं को प्रदर्शित (इस मामले में, न करने का विकल्प विकल्प कंस्ट्रक्टर्स पर कोष्ठकों)। यदि वे सुविधा नहीं जोड़ते हैं, तो हम यह नहीं पूछेंगे कि क्या इसका उपयोग पहली जगह में किया जाना चाहिए। इसका उपयोग नहीं करने का एक व्यावहारिक कारण यह है: new Object.func()इसके बराबर नहीं है new Object().func()। हमेशा कोष्ठक सहित, इस गलती को करने की संभावना समाप्त हो जाती है।
nmclean

2
यदि आप एक गलती करने की संभावना को खत्म करना चाहते हैं, जिसका आपको उपयोग करना चाहिए (new Object).func()। लेकिन मैं अतिरिक्त कोष्ठक और अतिरिक्त समान संकेतों का उपयोग करने पर विचार करता हूं, जैसा कि ==बनाम ===, आपकी भाषा नहीं सीखने के लिए एक बुरा बहाना है।
जीन विंसेंट

78

दोनों के बीच मतभेद हैं:

  • new Date().toString() पूरी तरह से काम करता है और वर्तमान तिथि देता है
  • new Date.toString()फेंकता है " TypeError: Date.toString एक निर्माता नहीं है "

यह इसलिए होता है क्योंकि new Date()और new Dateविभिन्न पूर्वता है। MDN के अनुसार जावास्क्रिप्ट ऑपरेटर पूर्वता तालिका का हिस्सा हम इस तरह दिखता है:

╔════════════╦═════════════════════════════╦═══════════════╦═════════════╗
 Precedence         Operator type         Associativity   Operators  
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
     18      Member Access                left-to-right   .        
             Computed Member Access       left-to-right    [  ]    
             new (with argument list)     n/a            new  (  ) 
╠════════════╬═════════════════════════════╬═══════════════╬═════════════╣
     17      Function Call                left-to-right   (  )     
             new (without argument list)  right-to-left  new        
╚════════════╩═════════════════════════════╩═══════════════╩═════════════╝

इस तालिका से निम्नानुसार है:

  1. new Foo() से अधिक पूर्वता है new Foo

    new Foo().ऑपरेटर के रूप में एक ही पूर्वता है

    new Foo.ऑपरेटर की तुलना में एक स्तर कम पूर्वता है

    new Date().toString() पूरी तरह से काम करता है क्योंकि यह मूल्यांकन करता है (new Date()).toString()

    new Date.toString()फेंकता है " TypeError: Date.toString एक कंस्ट्रक्टर नहीं है " क्योंकि (और तब "फंक्शन कॉल") की .तुलना में अधिक पूर्वता है new Dateऔर अभिव्यक्ति का मूल्यांकन(new (Date.toString))()

    … [ … ]ऑपरेटर के लिए एक ही तर्क लागू किया जा सकता है ।

  2. new Fooहै सही-से-बाएँ संबद्धता और के लिए new Foo()"संबद्धता" लागू नहीं है। मुझे लगता है कि व्यवहार में इससे कोई फर्क नहीं पड़ता। अतिरिक्त जानकारी के लिए यह SO प्रश्न देखें


क्या एक को दूसरे पर पसंद किया जाता है?

यह सब जानकर, यह माना जा सकता है कि new Foo()इसे पसंद किया जाता है ।


4
अंत में, कोई व्यक्ति जो वास्तव में प्रश्न का उत्तर देता है और सूक्ष्म अंतर को इंगित करता है!
gcampbell

वाह धन्यवाद। एक और भाषा की याद दिलाता है en.wikipedia.org/wiki/Brainfuck
जॉन हेनकेल

अच्छी तरह से समझाया गया है, वास्तव में यही कारण है कि new Foo()इसे क्यों पसंद किया जाना चाहिए new Foo। अब तक का सबसे अच्छा जवाब।
कोडलामा

बहुत बढ़िया जवाब, पूर्ववर्ती तालिका और साथ की व्याख्या इसे पूरी तरह से स्पष्ट करती है। खुशी है कि तुम यह कैसे लिखने के लिए ठीक करता है कि समझाने के new Object().something()साथ ही के रूप में (new Object()).something()
LittleTiger

1
महान व्याख्या लेकिन मैं निष्कर्ष से असहमत हूं और अभी भी लगता है कि यदि आप अपनी भाषा जानते हैं तो कोष्ठक का उपयोग करना ठीक नहीं है। यदि आप जेएस पूर्वता को नहीं जानते हैं तो बीटीडब्ल्यू का उपयोग कर सकते हैं (new Date).toString(), एक ही वर्ण गणना और इससे भी अधिक स्पष्ट new Date().toString
जीन विंसेंट

14

मुझे नहीं लगता कि जब आप "नया" ऑपरेटर का उपयोग कर रहे हैं तो कोई अंतर नहीं है। इस आदत में शामिल होने के बारे में सावधान रहें, क्योंकि कोड की ये दो लाइनें समान नहीं हैं:

var someVar = myFunc; // this assigns the function myFunc to someVar
var someOtherVar = myFunc(); // this executes myFunc and assigns the returned value to someOtherVar

1
इससे भी अधिक समस्याग्रस्त यदि आप अर्धविरामों को छोड़ने की आदत में हैं। ;-)
RobG

13

यदि आपके पास पास करने के लिए तर्क नहीं हैं, तो कोष्ठक वैकल्पिक हैं। उन्हें छोड़ सिर्फ चीनी है।


8
मैं सिंटैक्टिक नमक कहूंगा, लेकिन यमव।
थॉमस ईडिंग

मैं कहूंगा कि यदि आवश्यक नहीं है तो उन्हें जोड़ रहा है। :)
Cozzbie

8

https://people.mozilla.org/~jorendorff/es6-draft.html#sec-new-operator-runtime-semantics-evaluation

यहां ईएस 6 कल्पना का हिस्सा है जो परिभाषित करता है कि दो वेरिएंट कैसे संचालित होते हैं। नो-कोष्ठक संस्करण एक खाली तर्क सूची से गुजरता है।

दिलचस्प है, दो रूपों के अलग-अलग व्याकरणिक अर्थ हैं। यह तब होता है जब आप परिणाम के एक सदस्य तक पहुंचने का प्रयास करते हैं।

new Array.length // fails because Array.length is the number 1, not a constructor
new Array().length // 0

ईएस 5 और ईएस 3 में भी इसे अच्छी तरह से परिभाषित किया गया है - "कंस्ट्रक्टर पर [[कंस्ट्रक्ट]] को कॉल करने का परिणाम लौटाएं, कोई तर्क नहीं दे रहा है (यानी, तर्कों की एक खाली सूची)।"
बेंजामिन ग्रुएनबाम

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