2011-08-03 12 views
23

मुझे गहराई से नेस्टेड ऑब्जेक्ट प्रॉपर्टी जैसे YAHOO.Foo.Bar.xyz की जांच करनी है।जावास्क्रिप्ट में गहराई से घोंसला वाली वस्तु संपत्ति के अस्तित्व की जांच करने का सबसे आसान तरीका क्या है?

कोड मैं वर्तमान में उपयोग कर रहा हूँ

if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) { 
    // operate on YAHOO.Foo.Bar.xyz 
} 

है यह काम करता है, लेकिन अनाड़ी लग रहा है।

क्या ऐसी गहरी घोंसला वाली संपत्ति की जांच करने का कोई बेहतर तरीका है?

+3

क्या आप सिर्फ 'अगर (YAHOO.Foo.Bar.xyz) 'नहीं कर सकते हैं? –

+1

http://enterprise-js.com/34 <- है एक मजाक btw –

+5

@Michael, तो आप सिर्फ 'नहीं कर सकते हैं (YAHOO.Foo.Bar.xyz)' क्योंकि फू या बार अस्तित्व में नहीं है, तो , तो 'अगर (YAHOO.Foo.Bar.xyz)' एक अपवाद मध्यवर्ती मूल्यों कि अपरिभाषित हैं की भिन्नता की वजह से फेंक देते हैं। – jfriend00

उत्तर

18

यदि आप YAHOO.Foo.Bar को वैध ऑब्जेक्ट होने की उम्मीद करते हैं, लेकिन अपने कोड बुलेटप्रूफ को बस मामले में बनाना चाहते हैं, तो बस इसे चारों ओर पकड़ने की कोशिश करें और किसी त्रुटि वाले हैंडलर को किसी भी गायब होने दें खंड। उसके बाद, आप सिर्फ चार के बजाय एक if शर्त यह है कि अगर टर्मिनल संपत्ति मौजूद है की पहचान करेगा और एक पकड़ने हैंडलर चीजों को पकड़ने के लिए उपयोग कर सकते हैं मध्यवर्ती वस्तुओं मौजूद नहीं है:

try { 
    if (YAHOO.Foo.Bar.xyz) { 
     // operate on YAHOO.Foo.Bar.xyz 
} catch(e) { 
    // handle error here 
} 

या, पर कैसे अपने कोड के आधार काम करता है, तो यह और भी सिर्फ इस हो सकता है:

try { 
    // operate on YAHOO.Foo.Bar.xyz 
} catch(e) { 
    // do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist 
} 

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

सामान्य रूप से, कुछ जावास्क्रिप्ट डेवलपर्स अंडर-यूज का उपयोग/प्रयास करते हैं। मुझे लगता है कि अगर कभी एक बड़े फंक्शन ब्लॉक के चारों ओर एक ही कोशिश/पकड़ के साथ इनपुट की जांच कर रहे हैं और कोड को एक ही समय में बहुत सरल और अधिक पठनीय बनाते हैं तो मैं कभी-कभी 5-10 को प्रतिस्थापित कर सकता हूं। जाहिर है, जब यह उचित है तो विशेष कोड पर निर्भर करता है, लेकिन यह निश्चित रूप से विचार करने लायक है।

एफवाईआई, यदि सामान्य ऑपरेशन प्रयास/पकड़ के साथ अपवाद नहीं फेंकना है, तो यह बयान के गुच्छा से बहुत तेज़ हो सकता है।


आप अपवाद संचालक का उपयोग नहीं करना चाहते हैं, आप के लिए किसी भी मनमाने ढंग से पथ का परीक्षण करने के लिए एक समारोह बना सकते हैं:

function checkPath(base, path) { 
    var current = base; 
    var components = path.split("."); 
    for (var i = 0; i < components.length; i++) { 
     if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) { 
      return false; 
     } 
     current = current[components[i]]; 
    } 
    return true; 
} 

उदाहरण उपयोग:

var a = {b: {c: {d: 5}}}; 
if (checkPath(a, "b.c.d")) { 
    // a.b.c.d exists and can be safely accessed 
} 
+11

दुरुपयोग न करें इस तरह पकड़ने का प्रयास करें। प्रिय भगवान मेरी आंखें। और यहां तक ​​कि एक खाली पकड़ ब्लॉक भी। अगर मैंने कभी देखा है तो यह एक कोड गंध है। – Raynos

+6

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

+2

"अपवादों की घटना, विशेष परिस्थितियां जो प्रोग्राम निष्पादन के सामान्य प्रवाह को बदलती हैं।" मुझे यह दावा करने के लिए एक विशाल खिंचाव मिलता है कि मौजूद संपत्ति मौजूद नहीं है "विशेष स्थिति जो प्रोग्राम निष्पादन के सामान्य प्रवाह को बदलती है"। मुझे लगता है कि आप नौकरी के लिए गलत उपकरण का उपयोग कर रहे हैं। – Raynos

0

उपयोग एक try catch

a={ 
    b:{} 
}; 

//a.b.c.d?true:false; Errors and stops the program. 

try{ 
    a.b.c.d; 
} 
catch(e){ 
    console.log(e);//Log the error 
    console.log(a.b);//This will run 
} 
3

आप बल्कि "YAHOO.Foo पर" xyz "सदस्य के अस्तित्व से पथ की सत्यता की जांच करने के लिए, की जरूरत है।बार "वस्तु, यह शायद एक कोशिश पकड़ में कॉल रैप करने के लिए सबसे आसान हो जाएगा:

var xyz; 
try { 
    xyz = YAHOO.Foo.Bar.xyz; 
} catch (e) { 
    // fail; 
}; 

वैकल्पिक रूप से, आप कुछ स्ट्रिंग-काँग फू-जादू टीएम कर सकते हैं:

function checkExists (key, obj) { 
    obj = obj || window; 
    key = key.split("."); 

    if (typeof obj !== "object") { 
     return false; 
    } 

    while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ; 

    return (!key.length && typeof obj !== "undefined"); 
} 

इस प्रकार का उपयोग करें:

if (checkExists("YAHOO.Foo.Bar.xyz")) { 
    // Woo! 
}; 
+0

आप कभी भी कोशिश/पकड़ विधि के बजाय चेकएक्सिस्ट फ़ंक्शन में शामिल सबकुछ का उपयोग कब करेंगे? – jfriend00

+0

मुझे सिर्फ 'टाइपऑफ obj! == "ऑब्जेक्ट" परीक्षण का बिंदु नहीं दिख रहा है। प्रतिबंधक क्यों हो? – hugomg

+0

@ jfriend00: स्ट्रिंग विधि आपको उस बिंदु को खोजने की अनुमति देती है जहां चीजें टूट जाती हैं (यदि आप इसे भी चाहते हैं)। स्ट्रिंग के माध्यम से ऑब्जेक्ट विवरण पास करना कस्टम मॉड्यूल सिस्टम जैसे कुछ मामलों में भी समझ में आता है। – hugomg

0

मैं वास्तव में javascript convert dotnotation string into objects की डुप्लीकेट के रूप में प्रश्न को बंद करने के पक्ष में मत दिया

01।

हालांकि, मुझे लगता है कि यह एक अलग विषय है, लेकिन इस सवाल का जवाब अभी भी उपयोगी है अगर आप try-catch को हर समय नहीं करना चाहते हो सकता है।

6

इस उपयोगिता समारोह पर विचार करें:

function defined(ref, strNames) { 
    var name; 
    var arrNames = strNames.split('.'); 

    while (name = arrNames.shift()) {   
     if (!ref.hasOwnProperty(name)) return false; 
     ref = ref[name]; 
    } 

    return true; 
} 

उपयोग:

if (defined(YAHOO, 'Foo.Bar.xyz')) { 
    // operate on YAHOO.Foo.Bar.xyz 
} 

लाइव डेमो:http://jsfiddle.net/DWefK/5/

+0

मुझे लगता है कि आपको केवल सत्यता परीक्षण की बजाय, लूप परीक्षण में अपरिभाषित के लिए एक स्पष्ट जांच की आवश्यकता है। फिलहाल परिभाषित ({a: ''}, 'a.b') === सच। अच्छा दृष्टिकोण हालांकि, मुझे यह पसंद है! – codebox

+0

@codebox मैं अपने कोड से संतुष्ट नहीं था इसलिए मैंने एक पुनर्लेखन किया। तुम क्या सोचते हो? –

+0

यह अच्छा लग रहा है :) – codebox

7
var _ = {}; 

var x = ((YAHOO.Foo || _).Bar || _).xyz; 
+5

इस सप्ताह सबसे अस्पष्ट लाइन के लिए अंगूठे ऊपर। –

1

यह समस्या (coffeescript द्वारा काफी खूबसूरती से हल किया जाता है जो नीचे संकलित जावास्क्रिप्ट के लिए):

if YAHOO.Foo?.Bar?.xyz 
    // operate on YAHOO.Foo.Bar.xyz 
संबंधित मुद्दे

 संबंधित मुद्दे