2012-03-05 3 views
12

Ho un codice HTML che contiene una stringa JSON. Nella sul DOM pronto richiamata, ho qualcosa di simile:Come posso evitare che l'avviso 'Proprietà MyProp1 non sia mai stata definita su MyObject'?

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

Più tardi nel mio codice, scrivo qualcosa questo:

var SomeVar = MyObject.MyProp1; 

E poi quando ho eseguito il codice attraverso la chiusura di Google compiler, ricevo l'avviso

Proprietà MyProp1 non definita su MyObject.

Come deve essere scritto il codice in modo che non generi un avviso?

risposta

14

Il modo più pulito per rimuovere l'avviso è quello di definire la struttura del JSON. Questo può essere fatto utilizzando il tag @type:

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

Dove MyProp1 è il nome della proprietà, e string è il tipo.

Il compilatore di chiusura di Google rinominerà la variabile. Se non si desidera che, è necessario utilizzare le virgolette + staffe al posto del punto notazione:

MyObject['MyProp1'] 

Esempio: incolla il seguente nella Closure Compiler: uscita

// ==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(); 

:

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

Ok grazie, ora funziona! Nel complesso, è "meglio" utilizzare la notazione con notazione a virgola o tra parentesi o è solo una questione di stile/preferenza? Inoltre, ho intenzione di utilizzare il compilatore google e quindi reobfuscare il codice compilato in jscrambler. So che questo non impedirà il reverse engineering ma sto solo cercando di guadagnare tempo. Doppio lavoro di offuscamento? – frenchie

+1

@frenchie Generalmente, la notazione parentesi/punto è una questione di preferenza. Tuttavia, nel compilatore Closure, è necessario utilizzare la notazione delle parentesi per conservare i nomi. Tuttavia, la notazione a punti viene utilizzata nell'output compilato. E sì, la doppia offuscazione renderà sicuramente più difficile l'ingegneria inversa. Assicurati di testare le prestazioni del codice prima/dopo l'offuscamento. –

1

Invece di inserire il contenuto JSON nell'oggetto #TheJsonString come HTML, è necessario inserirlo nella pagina come javascript effettivo. Se il server sta generando il contenuto nella pagina, non c'è motivo per cui il server debba generare codice HTML da analizzare. Il server può semplicemente creare una variabile javascript all'interno di un tag script e inserire la reale struttura di dati javascript al suo interno.

JSON.parse() è molto utile per analizzare le risposte ajax, ma in realtà non è necessario quando il server può semplicemente mettere il javascript finito direttamente nella pagina generata.

+0

Sto inserendo le stringhe JSON in modo letterale, quindi nel browser sono all'interno di un div. Asp.net – frenchie

+0

@frenchie - So che li stai mettendo in un div. Sto chiedendo perché lo stai facendo quando potresti semplicemente inserirli direttamente in una variabile javascript. Non c'è motivo di metterli in forma di stringa nella tua pagina. Questo risolverebbe anche il problema di chiusura di Google perché sarebbe stato definito in vero javascript. – jfriend00

+1

Ci sono in realtà 12 stringhe json e i letterali vengono iniettati dal codice della pagina mastro dietro. Non voglio che il mio file .master abbia una brutta dichiarazione di valutazione del server. E questo non risolverà comunque il problema del compilatore poiché non ho le dichiarazioni json; sono valutati in fase di esecuzione. – 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> 

L'ho testato in questo modo, ma funziona perfettamente senza alcun avviso.

+0

Il problema è che non ho le stringhe json quando incollo il mio codice nel compilatore google: il json viene generato in fase di runtime ed è diverso per ogni utente. Più ci penso, più penso che la soluzione sia nell'eredità prototipale in cui ho bisogno di creare un oggetto e lanciare l'analisi del json, o qualcosa del genere. – frenchie

3

provare ad accedere alla proprietà in questo modo:

var SomeVar = MyObject['MyProp1']; 
7

per sopprimere questo avvertimento per una specifica funzione, è possibile utilizzare il @suppress della nota:

0.123.
/** 
* @suppress {missingProperties} 
*/ 
function useJsonObject() { ... } 

Per disattivare l'avviso a livello globale, utilizzare la bandiera jscomp_off compilatore per spegnere il missingPropertiesclass of warnings.