JS Quiz: Vero o Falso? Essere primitivo

Dopo aver imparato a distinguere quando le stringhe equivalgono a TRUE o a FALSE, la serie JS Quiz continua! Siete pronti ad un nuovo shock? Ecco qua!



<script> alert("ciao"==="ciao") //-> true :) alert("ciao"===new String("ciao")) //-> false :( </script> NOTA: le faccine tristi indicano un risultato che per qualcuno potrebbe essere inaspettato.

Assurdo!? Abbiamo usato l'operatore "===" ma stiamo pur sempre parlando di valori uguali entrambi di tipo stringa, no? Beh... no: nel secondo caso abbiamo confrontato un primitivo con un oggetto. I primitivi sono tre: String, Number, Boolean. Essenzialmente, non sono altro che dei valori, fine. Oltretutto, non essendo oggetti, l'unico modo per estenderli è estendere il loro costruttore, pratica assoltamente sconsigliata a meno che non stiate sviluppando un polyfill. Per farvi capire cosa intendo, ecco un esempio:
<script> A = new String("foo"); A.b = "bar"; alert("A.b = " + A.b); //-> bar :) a = "foo"; a.b = "bar"; alert("a.b = " + a.b); //-> Undefined :( String.prototype.b = "bar"; a = "foo"; alert("a.b = " + a.b); //-> bar :) </script> Ma se una stringa primitiva non è un oggetto String, com'è possibile che ("ciao".length==4) funzioni? Perchè JavaScript converte temporaneamente i primitivi nei relativi oggetti affinchè ne possano usare i metodi e le proprietà.

Si può fare anche il contrario: convertire gli oggetti nei loro primitivi tramite il metodo valueOf() o la cosiddetta "coercizione del tipo". Ecco alcuni esempi:
<script> alert(new Boolean(false)); //-> true :( alert(new Boolean(false).valueOf()); //-> false :) alert(new Boolean(false)===false); //-> false :( alert(new Boolean(false).valueOf()===false); //-> true :) alert(Boolean(new Boolean(false))); //-> true :( alert(!!+new Boolean(false)); //-> false :) alert(0?true:false); //-> false :) alert(new Number(0)?true:false); //-> true :( alert(new Number(8)===8); //-> false :( alert(new Number(8).valueOf()===8); //-> true :) alert(+new Number(8)===8); //-> true :) alert(Number(new Number(8))===8); //-> true :) alert(""?true:false); //-> false :) alert(new String("")?true:false); //-> true :( alert(new String("ciao")==="ciao") //-> false :( alert(new String("ciao").valueOf()==="ciao"); //-> true :) alert(""+new String("ciao")==="ciao"); //-> true :) alert(String(new String("ciao"))==="ciao"); //-> true :) </script> Se invece dell'operatore "===" usiamo "==" il problema non sussiste, ma entrambi gli approcci hanno i loro pro e contro. Ricordate però che quello raccomandato è il primo!