बिना संस्करण के विनाशकारी वस्तु


97

अगर कोई varकीवर्ड इसके सामने नहीं है, तो ऑब्जेक्ट डिस्ट्रक्टिंग एक एरर क्यों फेंकता है?

{a, b} = {a: 1, b: 2};

फेंकता SyntaxError: expected expression, got '='

निम्नलिखित तीन उदाहरण समस्याओं के बिना काम करते हैं

var {a, b} = {a: 1, b: 2};
var [c, d] = [1, 2];
    [e, f] = [1, 2];

बोनस प्रश्न: हमें varसरणी विनाशकारी की आवश्यकता क्यों नहीं है ?

मैं कुछ करने की समस्या में भाग गया

function () {
  var {a, b} = objectReturningFunction();

  // Now a and b are local variables in the function, right?
  // So why can't I assign values to them?

  {a, b} = objectReturningFunction();
}

जवाबों:


158

{...}जावास्क्रिप्ट में कई अर्थ वाले ऑपरेटरों से यह मुद्दा उपजा है ।

जब {एक स्टेटमेंट की शुरुआत होती है , तो यह हमेशा एक ब्लॉक का प्रतिनिधित्व करेगा , जिसे सौंपा नहीं जा सकता है। यदि यह बाद में एक अभिव्यक्ति के रूप में वक्तव्य में प्रकट होता है , तो यह एक वस्तु का प्रतिनिधित्व करेगा।

varइस तरह के अंतर बनाने में मदद करता है, क्योंकि यह एक के बाद नहीं किया जा सकता वक्तव्य इच्छा के रूप में, समूहीकरण कोष्टक :

( {a, b} = objectReturningFunction() );

उनके डॉक्स से: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Assignment_without_decutement

नोट: एक घोषणा के बिना ऑब्जेक्ट शाब्दिक विनाशकारी असाइनमेंट का उपयोग करते समय असाइनमेंट स्टेटमेंट के आसपास कोष्ठक (...) की आवश्यकता होती है।

{a, b} = {a: 1, b: 2} मान्य स्टैंड-अलोन सिंटैक्स नहीं है, क्योंकि बाईं ओर के {a, b} को ब्लॉक माना जाता है न कि ऑब्जेक्ट शाब्दिक।

हालाँकि, ({a, b} = {a: b, 2}) मान्य है, जैसा कि var {a, b} = {a: 1, b: 2} है

आपकी (...) अभिव्यक्ति को अर्धविराम से पहले करने की आवश्यकता है या इसका उपयोग पिछली पंक्ति में किसी फ़ंक्शन को निष्पादित करने के लिए किया जा सकता है।


यदि यह बाद में एक अभिव्यक्ति के रूप में वक्तव्य में प्रकट होता है, तो यह एक वस्तु का प्रतिनिधित्व करेगा। क्या इसका मतलब यह है कि हमारे पास कभी भी कोष्ठक को
समाहित करने की

समूहीकरण कोष्ठक की नोक एक महान है।
जेम्स स्मिथ

यह एक शानदार ढंग से अस्पष्ट सा ज्ञान है जिसने मुझे स्तब्ध कर दिया था। यह पूरे क्षेत्र में विनाशकारी होने की अनुमति देता है (अच्छी तरह से, - आपको अभी भी अपने चर घोषित करने की आवश्यकता है, निश्चित रूप से)। लेकिन यह बहुत अधिक गड़बड़ी पैदा किए बिना, दूसरे में एक वादा श्रृंखला के एक चरण से हल किए गए कई चर का उपयोग करने की आवश्यकता के दौरान प्रोमिस चेन का उपयोग करने की एक बाधा को हल करता है। धन्यवाद।
केविन तेलजेउर

23

यदि आप सेमीकॉलन के बिना जावास्क्रिप्ट लिखते हैं , तो 'असाइनमेंट विदाउट डिक्लेरेशन' सिंटैक्स को पूर्व में अर्धविराम के साथ पूर्वानुभव के लिए काम करना चाहिए।

let a, b

;({a, b} = objectReturningFunction()) // <-- note the preceding ;

बस इसे उजागर करना चाहता था क्योंकि इसने मुझे बाहर कर दिया था, और उम्मीद है कि दूसरों को कुछ समय बचा सकता है क्योंकि यह काम नहीं करता है और / या कोड स्वरूप जैसे अजीब परिणाम पैदा करता है prettier

वास्तव में, यह वास्तव में स्वीकृत उत्तर (उद्धृत डॉक्स की अंतिम पंक्ति) में है, लेकिन मिस करने में आसान है, खासकर एक उदाहरण देखे बिना!


1
हाँ। लोगों के अर्ध-कॉलनों का उपयोग करने का एक कारण!
jfriend00

1

यहाँ एक और तरीका है:

let {} = {a, b} = objectReturningFunction()

पेशेवरों:

  • किसी कोष्ठक की जरूरत नहीं है
  • किसी अर्धविराम की जरूरत नहीं है
  • अतिरिक्त काम एक गारंटीकृत नो-ऑप है (यह देखते हुए कि कोई अजीब चीजें नहीं चल रही हैं)

विपक्ष:

  • थोड़ा अजीब लगता है, हालांकि मेरी राय में !(){...}() आईआईएफई की तुलना में कोई भी अजीब नहीं है ।
  • यह वहाँ क्यों है के रूप में भ्रमित हो सकता है। यह पहली मुठभेड़ पर लोगों को फेंकने की गारंटी है, इसलिए मैं इसे एक-बंद के रूप में उपयोग करने के खिलाफ सलाह दूंगा।

Iife की तरह महसूस करता की तरह करने के लिए और अधिक तुलनीय हैं ;({ a, b })की तुलना में let {} = { ... }। हालांकि अच्छी चाल। :)
शकरस्टर

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