2012-09-23 9 views
10

Ho visto alcuni esempi che mostrano che Firefox supporta una sorta di sintassi JavaScript lungo le linee di *something* if *expression*;.* qualcosa * if * espressione * sintassi in JavaScript (FF)

Come esempio di ciò di cui sto parlando, vedere this MDN article, che contiene il seguente esempio:

var evens = [i for each (i in range(0, 21)) if (i % 2 == 0)]; 

Le mie domande sono:

Che nome sarebbe stato dato per descrivere questo tipo di sintassi? Principalmente voglio sapere questo in modo che io possa Google e leggere di più su di esso. Ho provato su Google il meglio che riesco a trovare, ma non sono riuscito a mettere insieme i termini giusti per ottenere risultati utili.

Questa sintassi può esistere in altri punti al di fuori della comprensione di un array? Mi sembra di aver visto altri esempi di questo utilizzo al di fuori di un array (come nell'esempio sopra), ma non ne sono sicuro.

Dove posso leggere di più su questa sintassi?

Altri browser supportano questo oltre a Firefox?

Questa funzione è in ES5 o è pianificata per ES-harmony?

+0

_ "Che nome sarebbe stato dato per descrivere questo tipo di sintassi?" _ - L'articolo si è collegato al definisce "Array comprensioni del testo". – nnnnnn

+0

Potrei sbagliarmi, ma penso che quel termine si riferisse a 'for each' all'interno di una parte dell'array. Penso di aver visto questa diversa sintassi 'if' usata al di fuori degli array, ma non ne sono sicuro. ? –

+0

_non è solo la comprensione gamma molto più compatto, ma in realtà è più facile da leggere, ** una volta che si ha familiarità con il concetto ** ._ oserei usando solo che una volta che sono certo tutti sanno la sintassi. Il manutentore di essere uno psicopatico violento e tutto ... – Laoujin

risposta

4

Come altri hanno notato, questo è chiamato "Array Comprensioni" ed è uno dei tanti, molte caratteristiche suggeriti per ECMAScript Harmony:

http://wiki.ecmascript.org/doku.php?id=harmony:array_comprehensions

Tuttavia, come per quasi tutti i "feature" Harmony , Non penso che ci sia una vera idea riguardo alla possibilità di includerlo nella versione finale. Puoi usarlo in Firefox come parte di "JavaScript 1.7" (una nebulosa " specifica" in realtà si applica solo a materiale basato su Mozilla); tuttavia, è meglio evitare la sintassi FF specifica, specialmente quando causerebbe errori di sintassi in altri browser.

Puoi leggere di più a riguardo eseguendo una ricerca su Google per "Array Comprehensions", ma come ho detto, non è uno strumento molto utile a causa della sua natura specifica di Mozilla.

È possibile ottenere un effetto simile senza molto più codice con il metodo reduce() Array introdotto nel ES5:

//JavaScript has no "range" function, so let's make one 
var range = function (begin, length) { 
    var i, ret = []; 
    for (i = begin; i < begin + length; i++) { 
     ret.push(i); 
    } 
    return ret; 
}; 

var evens = range(0, 21).reduce(function (arr, cur) { 
    if (cur % 2 === 0) arr.push(cur); 
    return arr; 
}, []); 

che potrebbe essere un po 'prolissa rispetto a quello che stavi cercando (anche tenendo presente che abbiamo dovuto creare una funzione range()). Ma è una soluzione relativamente compatta che non richiede un sacco di "setup" e si limita principalmente alla risoluzione del problema: filtrare gli elementi da un array per formare un secondo array.

Sono stato in grado di ridurlo a una linea singola, ma diventa un po 'spiacevole da mantenere, quindi ho deciso di suggerire la versione a due linee, invece.Nel caso siate interessati al one-liner, eccola:

//Don't forget to define "range()" 
var evens = range(0, 21).reduce(function (arr, cur) { 
    return (cur % 2 === 0) ? (arr.push(cur) && arr) : arr; 
}, []); 

Ancora una volta, questo è il codice ES5. Se vuoi che funzioni nei browser più vecchi, dovrai fornire uno shim per fornire supporto per Array.reduce(). MDN ha uno qui:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/Reduce

UPDATE:

Sembra che avrei dovuto usare filter() invece di reduce(). Rende il codice molto più pulito. Grazie all'OP per averlo suggerito!

var evens = range(0,21).filter(function (cur) { return cur % 2 === 0; }); 

Anche in questo caso, è filter() ES5, quindi avrai bisogno di uno spessore al fine di assicurare che possa funzionare correttamente su browser più vecchi.

+1

+1, ma "JavaScript 1.7" non è un tipo di standard. JavaScript è l'implementazione proprietaria di Mozilla di ECMAScript per l'utilizzo nei browser. Non c'è nemmeno una specifica per questo, l'unica documentazione che si avvicina è il [riferimento on-line] (https://developer.mozilla.org/en-US/docs/JavaScript/Reference), che viene mantenuto come una wiki della comunità. – RobG

+0

+1, grazie per tutte le informazioni! Userei 'filter' invece di' reduce' per la variante ES5. Ma se sto lavorando a un progetto che sto bene solo con FF, sto anche usando le funzionalità di JS1.7. –

+0

@RobG Grazie. Aggiornato. – Pete

2

Questo tipo di istruzione è noto come list comprehension. Python ha buoni esempi con sintassi molto simile.

+0

più 1, grazie! –