2012-03-05 28 views
12

मेरे पास कुछ HTML है जिसमें JSON स्ट्रिंग है। डोम तैयार कॉलबैक पर में, मैं कुछ इस तरह है:मैं 'MyPbject पर संपत्ति MyProp1 कभी परिभाषित नहीं' चेतावनी को कैसे रोक सकता हूं?

MyObject = JSON.parse($('#TheJsonString').html()); 

मेरी कोड में बाद में, मैं कुछ इस बारे में:

var SomeVar = MyObject.MyProp1; 

और फिर जब मैं गूगल बंद के माध्यम से कोड को चलाने संकलक, मैं चेतावनी

संपत्ति MyProp1 MyObject पर परिभाषित कभी नहीं मिलता है।

कोड को कैसे लिखा जाना चाहिए ताकि यह चेतावनी उत्पन्न न करे?

उत्तर

14

साफ चेतावनी दूर करने के लिए जिस तरह से JSON की संरचना को परिभाषित कर रहा है। यह @type टैग का उपयोग किया जा सकता है:

/** @type {{MyProp1:string}} */ 

कहाँ MyProp1 गुण का नाम है, और string प्रकार है।

गूगल की क्लोजर संकलक चर नाम बदल देगा।

MyObject['MyProp1'] 

उदाहरण: आपको लगता है कि नहीं करना चाहती हैं, तो आप बिंदु संकेतन के बजाय उद्धरण + कोष्ठक का उपयोग करने के

// ==ClosureCompiler== 
// @compilation_level ADVANCED_OPTIMIZATIONS 
// ==/ClosureCompiler== 

var MyObject; 
function x() { // Magic happens at the next line 
    /** @type {{MyProp1:string}}*/ 
    MyObject = JSON.parse(prompt('')); 
} 
function afterX() { 
    var SomeVar = MyObject.MyProp1; 
    alert(SomeVar); 
} 
x(); 
afterX(); 

आउटपुट:: Closure Compiler में निम्नलिखित पेस्ट

var a;a=JSON.parse(prompt(""));alert(a.a); 
+0

ठीक है धन्यवाद, अब यह काम करता है! कुल मिलाकर, क्या यह डॉट-नोटेशन बनाम ब्रैकेट नोटेशन का उपयोग करने के लिए "बेहतर" है या शैली/वरीयता का मामला है? इसके अलावा, मैं Google कंपाइलर का उपयोग करने की योजना बना रहा हूं और फिर जेएसक्रैम्बलर में संकलित कोड को फिर से भरना चाहता हूं। मुझे पता है कि यह रिवर्स इंजीनियरिंग को नहीं रोकेगा लेकिन मैं केवल समय खरीदना चाहता हूं। डबल obfuscation काम करेंगे? – frenchie

+1

@frenchie आम तौर पर, ब्रैकेट/डॉट नोटेशन वरीयता का मामला है। हालांकि, क्लोजर कंपाइलर में, नामों को संरक्षित करने के लिए ब्रैकेट नोटेशन का उपयोग किया जाना चाहिए। हालांकि, संकलित आउटपुट में डॉट-नोटेशन का उपयोग किया जाता है। और हां, डबल obfuscation वास्तव में रिवर्स इंजीनियरिंग कठिन बना देगा। सुनिश्चित करें कि आप obfuscation से पहले/बाद में कोड के प्रदर्शन का परीक्षण करते हैं। –

1

जेएसओएन सामग्री को #TheJsonString ऑब्जेक्ट में HTML के रूप में डालने के बजाय, आपको इसे अपने पृष्ठ में वास्तविक जावास्क्रिप्ट के रूप में रखना चाहिए। यदि सर्वर पृष्ठ में सामग्री उत्पन्न कर रहा है, तो कोई कारण नहीं है कि सर्वर को HTML उत्पन्न करने की आवश्यकता है जिसे आप फिर पार्स करते हैं। सर्वर सिर्फ एक स्क्रिप्ट टैग के अंदर जावास्क्रिप्ट चर बना सकता है और इसमें वास्तविक जावास्क्रिप्ट डेटा संरचना डाल सकता है।

JSON.parse() AJAX प्रतिक्रियाओं को पार्स करने के लिए बहुत उपयोगी है, लेकिन वास्तव में यह आवश्यक नहीं है जब सर्वर पहले जेनरेट पृष्ठ में सीधे जावास्क्रिप्ट को सीधे स्थान पर रख सके।

+0

मैं तो एक शाब्दिक में json तार डाल रहा हूं ब्राउज़र वे एक div के अंदर कर रहे हैं में। Asp.net – frenchie

+0

@frenchie - मुझे पता है कि आप उन्हें एक div में डाल रहे हैं। मैं पूछ रहा हूं कि आप ऐसा क्यों कर रहे हैं जब आप उन्हें सीधे जावास्क्रिप्ट चर में डाल सकते हैं। उन्हें अपने पृष्ठ में स्ट्रिंग फॉर्म में रखने का कोई कारण नहीं है। यह Google बंद करने के मुद्दे को भी हल करेगा क्योंकि उन्हें वास्तविक जावास्क्रिप्ट में परिभाषित किया जाएगा। – jfriend00

+1

वास्तव में 12 जेसन स्ट्रिंग हैं और अक्षर को मास्टर पेज कोड से इंजेक्शन दिया जाता है। मैं नहीं चाहता कि मेरी .master फ़ाइल में बदसूरत सर्वर eval स्टेटमेंट हो। और यह संकलक समस्या को हल नहीं करेगा क्योंकि मेरे पास जेसन स्टेटमेंट नहीं है; उनका रनटाइम पर मूल्यांकन किया जाता है। – frenchie

0
<!DOCTYPE html> 
<html> 
<head></head> 
<body> 
<div id="TheJsonString"> 
    {"bindings": "hr", "method":"asd"} 
</div> 
<script type="text/javascript" src="jquery-1.7.1.min.js"></script> 
<script type="text/javascript"> 
    var MyObject = JSON.parse($('#TheJsonString').html()); 

    var SomeVar = MyObject.bindings; 

    console.log(SomeVar); 
</script> 
</body> 
</html> 

मैं इसे इस तरह का परीक्षण किया है, लेकिन यह किसी भी चेतावनी के बिना ठीक काम करता है।

+0

समस्या यह है कि मैं json तार जब मैं गूगल संकलक में मेरी कोड पेस्ट नहीं है: json कार्यावधि में उत्पन्न होता है और प्रत्येक उपयोगकर्ता के लिए अलग है। अधिक मैं इसके बारे में सोचते हैं, मुझे लगता है कि और अधिक समाधान prototypial विरासत में वह जगह है जहाँ मैं एक वस्तु बना सकते हैं और इस तरह json की पार्स, या कुछ कास्ट करने के लिए की जरूरत है। – frenchie

3

इस तरह से संपत्ति एक्सेस करके देखें:

var SomeVar = MyObject['MyProp1']; 
7

एक विशेष समारोह के लिए यह चेतावनी को दबाने के लिए, आपको @suppress एनोटेशन का उपयोग कर सकते हैं:

0,123,
/** 
* @suppress {missingProperties} 
*/ 
function useJsonObject() { ... } 

इस चेतावनी विश्व स्तर पर बंद करने के लिए, missingPropertiesclass of warnings बंद करने के लिए jscomp_off संकलक ध्वज का उपयोग करें।