Domanda

Prova eseguire il seguente in JavaScript:

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

Ho appena imparato nel modo più duro che JavaScript pensa lo zero indica un ottale intero , e poiché non v'è "8" o "9" in base-8, la funzione restituisce zero. Piaccia o no, questo legato alla progettazione .

Quali sono le soluzioni?

Nota. Per completezza, sto per inviare una soluzione, ma è una soluzione che io odio, quindi si prega di inviare altre risposte / migliori


Aggiornamento:

La 5a edizione della norma JavaScript ( ECMA-262 ) introduce una modifica sostanziale che elimina questo comportamento. Mozilla ha una buona scrivere-up .

È stato utile?

Soluzione

Questa è una Gotcha JavaScript comune con una soluzione semplice:

specificare la base , o 'radix', in questo modo:

parseInt('08',10); // 8

Si potrebbe anche usare Numero :

Number('08'); // 8

Altri suggerimenti

Se so il tuo valore sarà nel range firmato intero a 32 bit, quindi ~~x farà la cosa giusta in tutti gli scenari.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

Se guardi in alto binario non (~), le specifiche richiede una conversione "ToInt32" per l'argomento che fa la conversione ovvio per un Int32 ed è specificato per costringere NaN valori a zero.

Sì, questo è incredibilmente hacker, ma è così comoda ...

documentazione parseInt , utilizzare l'argomento radix opzionale per specificare base-10:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

Questa mi sembra pedante, confuso, e verbose (in realtà, un argomento in più in ogni singolo parseInt?) Quindi spero ci sia un modo migliore.

function parseDecimal(s) { return parseInt(s, 10); }

modifica: rendere la propria funzione, di fare ciò che si vuole veramente, è solo un'opzione se non vi piace l'aggiunta del", 10" tutto il tempo per il parseInt call (). Ha lo svantaggio di essere una funzione non standard:. Più conveniente per voi, se lo si utilizza molto, ma forse più confuso per gli altri

Specifica la base:

var number = parseInt(s, 10);

Sarebbe molto cattivo per sostituire parseInt con una versione che assume decimale se non ha secondo parametro? (Nota - non testato)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

Che ne dite di questo per decimali:

('09'-0) === 9  // true

('009'-0) === 9 // true
  

Si può anche, invece di utilizzare parseFloat o parseInt, utilizzare l'operatore unario ( + ).

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

e per buona misura

+"09.09"
// => 9.09

MDN link

  

L'operatore più unario precede il suo operando e valuta al suo operando, ma tenta di convertirlo in un numero, se non lo è già. Anche se la negazione unaria (-) anche in grado di convertire i non-numeri, più unario è il modo più veloce e preferenziale di convertire qualcosa in un certo numero , perché non esegue altre operazioni sul numero

Se hai fatto un po 'di codifica già con parseInt e non si vuole aggiungere", 10" a tutto ciò, si può semplicemente ignorare la funzione di rendere la base 10 di default:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

Questo può confondere un lettore di seguito, in modo da fare una funzione parseInt10 () potrebbe essere più auto-esplicativo. Personalmente preferisco usando una funzione semplice che dover aggiungere", 10" tutto il tempo - solo crea maggiori opportunità per gli errori

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top