javascript - अपरिभाषित हो सकने वाले डेटा पर कॉलिंग फ़ंक्शंस को कैसे संभालें?




reactjs (2)

आपको वास्तव में यहाँ क्या चाहिए, इसे वैकल्पिक चैनिंग कहा जाता है:

obj?.a?.b?.c // no error if a, b, or c don't exist or are undefined/null

?. अस्तित्वगत ऑपरेटर है और यह आपको संपत्तियों को सुरक्षित रूप से एक्सेस करने की अनुमति देता है और अगर संपत्ति गायब है तो इसे फेंक नहीं देगा। हालाँकि वैकल्पिक चैनिंग अभी जावास्क्रिप्ट का हिस्सा नहीं है , लेकिन प्रस्तावित किया गया है, TC39 के राज्य 1 को देखें

लेकिन, परदे के पीछे और Maybe एक वर्ग का उपयोग करते हुए, आप वैकल्पिक चेनिंग को लागू कर सकते हैं और श्रृंखला के विफल होने पर एक डिफ़ॉल्ट मान लौटा सकते हैं।

एक wrap() फ़ंक्शन का उपयोग उन वस्तुओं को लपेटने के लिए किया जाता है, जिस पर आप वैकल्पिक चेनिंग लागू करना चाहते हैं। आंतरिक रूप से, wrap आपके ऑब्जेक्ट के चारों ओर एक प्रॉक्सी बनाता है और Maybe रैपर का उपयोग करके लापता मानों का प्रबंधन करता है।

श्रृंखला के अंत में, आप डिफ़ॉल्ट मान के साथ getOrElse(default) करते हुए मान को getOrElse(default) जो श्रृंखला मान्य नहीं होने पर वापस आ जाता है:

const obj = {
  a: 1,
  b: {
    c: [4, 1, 2]
  },
  c: () => 'yes'
};

console.log(wrap(obj).a.getOrElse(null)) // returns 1
console.log(wrap(obj).a.b.c.d.e.f.getOrElse(null)) // returns null
console.log(wrap(obj).b.c.getOrElse([])) // returns [4, 1, 2]
console.log(wrap(obj).b.c[0].getOrElse(null)) // returns 4
console.log(wrap(obj).b.c[100].getOrElse(-1)) // returns -1
console.log(wrap(obj).c.getOrElse(() => 'no')()) // returns 'yes'
console.log(wrap(obj).d.getOrElse(() => 'no')()) // returns 'no'

wrap(obj).noArray.getOrElse([1]).forEach(v => console.log(v)) // Shows 1
wrap(obj).b.c.getOrElse([]).forEach(v => console.log(v)) // Shows 4, 1, 2

पूरा उदाहरण:

class Maybe {
  constructor(value) {
    this.__value = value;
  }
  static of(value){
    if (value instanceof Maybe) return value;
    return new Maybe(value);
  }
  getOrElse(elseVal) {
    return this.isNothing() ? elseVal : this.__value;
  }
  isNothing() {
    return this.__value === null || this.__value === undefined;
  }
  map(fn) {  
    return this.isNothing()
      ? Maybe.of(null)
      : Maybe.of(fn(this.__value));
  }
}

function wrap(obj) {
  function fix(object, property) {
    const value = object[property];
    return typeof value === 'function' ? value.bind(object) : value;
  }
  return new Proxy(Maybe.of(obj), {
    get: function(target, property) {
      if (property in target) {
          return fix(target, property);
      } else {
        return wrap(target.map(val => fix(val, property)));
      }
    }
  });
}

const obj = { a: 1, b: { c: [4, 1, 2] }, c: () => 'yes' };

console.log(wrap(obj).a.getOrElse(null))
console.log(wrap(obj).a.b.c.d.e.f.getOrElse(null))
console.log(wrap(obj).b.c.getOrElse([]))
console.log(wrap(obj).b.c[0].getOrElse(null))
console.log(wrap(obj).b.c[100].getOrElse(-1))
console.log(wrap(obj).c.getOrElse(() => 'no')())
console.log(wrap(obj).d.getOrElse(() => 'no')())

wrap(obj).noArray.getOrElse([1]).forEach(v => console.log(v)) // Shows 1
wrap(obj).b.c.getOrElse([]).forEach(v => console.log(v)) // Shows 4, 1, 2

मैं मुख्य रूप से रिएक्ट के साथ काम करता हूं और अक्सर पाता हूं कि जब मैं एक फ़ंक्शन लिखता हूं जो एक घटक की स्थिति पर निर्भर करता है, तो मुझे यह देखने के लिए चेक करना होगा कि क्या किसी भी कार्य को करने से पहले राज्य के टुकड़े को परिभाषित किया गया है।

उदाहरण के लिए: मेरे पास एक फ़ंक्शन है जो डेटाबेस से प्राप्त वस्तुओं की एक सरणी पर .map() का उपयोग करता है और सरणी में प्रत्येक ऑब्जेक्ट के लिए jsx उत्पन्न करता है। इस फ़ंक्शन को मेरे घटक के render() फ़ंक्शन में कहा जाता है। पहली बार render() कहा जाता है, प्रारंभिक सरणी खाली है। यह एक त्रुटि है, क्योंकि, निश्चित रूप से, सरणी का पहला सूचकांक अपरिभाषित है।

मैं यह देखने के लिए एक सशर्त जांच करके इसे दरकिनार कर रहा हूं कि क्या सरणी का मान अपरिभाषित है या नहीं। अगर हर बार एक स्टेटमेंट लिखने की यह प्रक्रिया थोड़ी अनाड़ी लगती है और मैं सोच रहा था कि क्या इस चेक को करने का एक बेहतर तरीका है या इसे पूरी तरह से बचने का तरीका है।


मानचित्र का उपयोग करने से पहले सरणी की जाँच करें:

arr && arr.map()

या,

arr && arr.length && arr.map() // if you want to map only if not empty array

या,

हम भी इस तरह का उपयोग कर सकते हैं (जैसा कि devserkan द्वारा टिप्पणी की गई है):

(arr || []).map()

आपकी टिप्पणी के अनुसार:

मेरी इच्छा है कि C # के साथ एक सुरक्षित नेविगेशन ऑपरेटर था (गिरफ्तारी? .Map ())

हाँ, ज़ाहिर है। इसे जावास्क्रिप्ट में वैकल्पिक चैनिंग कहा जाता है जो अभी भी प्रस्ताव में है। यदि इसे स्वीकार किया जाता है, तो आप इस तरह का उपयोग कर सकते हैं:

arr?.map()

आप इसे स्टेज 1 में देख सकते हैं जिसके लिए आप babel प्रीसेट स्टेज 1 का उपयोग कर सकते हैं

लेकिन जाहिर है, चेकिंग सरणी लंबाई को छोड़कर, आपकी आवश्यकता पूरी नहीं होगी:

यह एक त्रुटि है, क्योंकि, निश्चित रूप से, सरणी का पहला सूचकांक अपरिभाषित है।

इसलिए, मैं आपको उपयोग करने का सुझाव देता हूं:

arr && arr.length && arr.map()




reactjs