2011-11-20 17 views
7

Questa domanda segue: Why does Closure compiler rename properties of an extern type? La risposta di John a questa domanda solleva questa seconda domanda.Posso dire al compilatore Closure, solo per determinati tipi, di interrompere la ridenominazione delle proprietà?

Se io dichiaro il tipo extern come suggerito:

/** @interface */ 
function SpanishNoun() {} 
/** @type {string} */ 
SpanishNoun.prototype.english; 
/** @type {string} */ 
SpanishNoun.prototype.spanish; 

poi Javascript come:

/** 
* @param {SpanishNoun} n 
*/ 
exp.foo = function (n) { 
    console.log(n.english, n.spanish, n['english'], n['spanish']); 
} 

compilerà, come desiderato, a:

function(a){console.log(a.english,a.spanish,a.english,a.spanish)}; 

Le proprietà non sono ribattezzato come al solito. Senza la dichiarazione esterna, il codice compilato sarà simile a:

function(a){console.log(a.a,a.c,a.english,a.spanish) 

Va bene. Il problema è che il compilatore ha smesso di rinominare "inglese" e "spagnolo" in tutti i posti. Anche se non sono di tipo extern.

/** 
* @param {AnotherType} 
*/ 
exp.bar = function (c) { 
    c.other = c.english; 
} 

compila per ...

function(a){a.b=a.english}; 

Esiste un modo per fermare questo? Se no, c'è una ragione per questo comportamento?

Volevo utilizzare i tipi extern per gestire cose come oggetti JSON che hanno origine dal server e non hanno proprietà rinominate. Ma se ogni volta che dichiaro un extern che sto mangiando la capacità del compilatore di rinominare e ridurre il codice, troverò un altro modo. Forse prenderò la proprietà che rinomina la mappa generata dal compilatore (--property_map_output_file) e la uso sul server quando si generano le risposte JSON.

+0

Questo è il comportamento standard di Closure per evitare errori (puoi leggere il sito Web Closure per capire perché è necessario). Chiusura rinomina sempre lo stesso nome di proprietà con lo stesso nome di maglio. D'altra parte, non rinominare tutte le proprietà (indipendentemente da dove) dello stesso nome, perché in pratica il non-renaming si sta semplicemente rinominando. C'è un flag (chiamato "ambiguateProperties" o qualcosa di simile) che puoi attivare per evitare questo, ma è solo sperimentale. –

+0

Il motivo di questo comportamento standard è che è possibile scrivere una funzione che accetta solo un oggetto e utilizza la proprietà 'english' su quell'oggetto. La chiusura non ha modo di sapere quale oggetto stai passando e se la proprietà 'english' di quell'oggetto è stata rinominata o meno. Poiché JavaScript è un linguaggio non tipizzato, puoi fare questo genere di cose (passando in oggetti diversi di classi diverse), quindi il compilatore deve rinominare lo stesso nome di proprietà sulla stessa stringa per evitare di non essere in grado di decidere quale versione di il nome a cui è mappato. –

risposta

3

Il compilatore di chiusura può rinominare in base ai tipi: https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming Questo migliora altre ottimizzazioni come la rimozione di inlining e dead code pure. Questo è usato internamente a Google ma ha un costo in quanto può introdurre alcuni scenari di debug complessi se "giace" nelle dichiarazioni del tipo.

+0

Questo link non funziona più. Forse questo è un nuovo collegamento (non più sperimentale): https://github.com/google/closure-compiler/wiki/Type-Based-Property-Renaming – ChrisW

+0

Grazie aggiornato l'URL. – John

Problemi correlati