Quali sono i casi d’uso per fare una new String("already a string")
?
Qual è il punto centrale?
C’è pochissimo uso pratico per gli oggetti String
come creato da new String("foo")
. L’unico vantaggio che un object String
ha su un valore stringa primitivo è che come object può memorizzare proprietà:
var str = "foo"; str.prop = "bar"; alert(str.prop); // undefined var str = new String("foo"); str.prop = "bar"; alert(str.prop); // "bar"
Se non sei sicuro di quali valori possono essere passati al tuo codice, ti suggerisco di avere problemi più grandi nel tuo progetto. Nessun object JavaScript nativo, libreria principale o metodo DOM che restituisce una stringa restituirà un object String
anziché un valore stringa. Tuttavia, se vuoi essere assolutamente sicuro di avere un valore stringa piuttosto che un object String
, puoi convertirlo come segue:
var str = new String("foo"); str = "" + str;
Se il valore che stai controllando può essere qualsiasi object, le tue opzioni sono le seguenti:
Non preoccuparti degli oggetti String e usa solo typeof . Questa sarebbe la mia raccomandazione.
typeof str == "string"
.
Usa instanceof e typeof . Questo di solito funziona ma ha lo svantaggio di restituire un falso negativo per un object String creato in un’altra finestra.
typeof str == "string" || str instanceof String
Usa la digitazione anatra . Verificare l’esistenza di uno o più metodi specifici della stringa, ad esempio sottostringa () o toLowerCase (). Questo è chiaramente impreciso, poiché restituirà un falso positivo per un object che ha un metodo con il nome che stai controllando, ma nella maggior parte dei casi sarà abbastanza buono.
typeof str == "string" || typeof str.substring == "function"
I creator di Javascript hanno creato wrapper per tipi di base come string o int solo per renderlo simile a java. Sfortunatamente, se someome fa una nuova String (“x”) il tipo di elemento sarà “object” e non “string”.
var j = new String ("x"); j === "x" // false j == "x" // true
String
oggetti String
possono avere proprietà, mentre le primitive stringa non possono:
var aStringObject=new String("I'm a String object"); var aStringPrimitive="I'm a string primitive"; aStringObject.foo="bar"; console.log(aStringObject.foo); //--> bar aStringPrimitive.foo="bar"; console.log(aStringPrimitive.foo); //--> undefined
E gli oggetti String
possono essere ereditati da, mentre i primitivi stringa non possono:
var foo=Object.create(aStringObject); var bar=Object.create(aStringPrimitive); //--> throws a TypeError
String
oggetti String
possono essere solo uguali a se stessi, non altri oggetti String
con lo stesso valore, mentre le primitive con lo stesso valore sono considerate uguali:
var aStringObject=new String("I'm a String object"); var anotherStringObject=new String("I'm a String object"); console.log(aStringObject==anotherStringObject); //--> false var aStringPrimitive="I'm a string primitive"; var anotherStringPrimitive="I'm a string primitive"; console.log(aStringPrimitive==anotherStringPrimitive); //--> true
Potresti implementare un comportamento simile a overload:
function overloadedLikeFunction(anArgument){ if(anArgument instanceof String){ //do something with a String object } else if(typeof anArgument=="string"){ //do something with a string primitive } }
O specificare lo scopo dell’argomento:
function aConstructorWithOptionalArugments(){ this.stringObjectProperty=new String("Default stringObjectProperty value"); this.stringPrimitiveProperty="Default stringPrimitiveProperty value"; for(var argument==0;argument
O traccia gli oggetti:
var defaultStringValue=new String("default value"); var stringValue=defaultStringValue; var input=document.getElementById("textinput") //assumes there is an text element with id equal to "textinput" input.value=defaultStringValue; input.onkeypress=function(){ stringValue=new String(this.value); } function hasInputValueChanged(){ //Returns true even if the user has entered "default value" in the return stringValue!=defaultStringValue; }
L'esistenza degli oggetti String
e delle primitive delle stringhe fornisce effettivamente due "tipi" di stringhe in Javascript con comportamenti diversi e, di conseguenza, usi. Questo vale per Boolean
oggetti Boolean
e Number
e le loro rispettive primitive.
Attenzione, tuttavia, al passaggio di stringhe (o di altre primitive) come valore di this
quando si utilizzano i metodi della funzione bind()
, call()
e apply()
, poiché il valore verrà convertito in un object String
(o in un Boolean
o in un Number
object, a seconda della primitiva) prima di essere usato come this
:
function logTypeofThis(){ console.log(typeof this); } var aStringPrimitive="I'm a string primitive"; var alsoLogTypeofThis=logTypeofThis.bind(aStringPrimitive); console.log(typeof aStringPrimitive); //--> string; logTypeofThis.call(aStringPrimitive); //--> object; logTypeofThis.apply(aStringPrimitive); //--> object; alsoLogTypeofThis(); //--> object;
E tipi di resi inaspettati / contro-intuitivi:
var aStringObject=new String("I'm a String object"); console.log(typeof aStringObject); //--> object aStringObject=aStringObject.toUpperCase(); console.log(typeof aStringObject); //--> string
Puoi usare instanceof
se vuoi davvero essere paranoico:
if(typeof x === "string" || x instanceof String)
L’ operatore instanceof
gestirà correttamente anche le sottoclassi di String:
obj instanceof ConstructorFunction
funziona controllando seConstructorFunction.prototype
trova nella catena di prototipi diobj
.
Non penso di aver mai effettivamente usato la class String in JavaScript, ma non c’è niente di sbagliato nell’essere paranoico e puntare alla correttezza.
Nella maggior parte dei casi lavori da solo e puoi controllarti, o in una squadra e c’è una linea guida del team, o puoi vedere il codice con cui stai lavorando, quindi non dovrebbe essere un problema. Ma puoi sempre essere più sicuro:
var obj = new String("something"); typeof obj; // "object" obj = ""+obj; typeof obj; // "string"
Aggiornare
Non ho pensato molto alle implicazioni di questo, anche se sembra funzionare:
var obj = new String("something"), obj2 = "something else"; obj.constructor === String; // true obj2.constructor === String; // true
Certo, dovresti controllare se l’object ha un costruttore (cioè se è un object).
Quindi potresti avere:
isString(obj) { return typeof obj === "string" || typeof obj === "object" && obj.constructor === String; }
Anche se ti suggerisco di usare solo typeof e “string”, un utente dovrebbe sapere di passare attraverso una normale stringa letterale.
Dovrei notare che questo metodo è probabilmente suscettibile a qualcuno che crea un object e imposta il suo costruttore come String
(che sarebbe in effetti completamente oscuro), anche se non è una stringa …
Object.prototype.toString.call(aVariable) == '[object String]'
Perché hai bisogno di verificare se è una stringa?
Basta controllare se è definito o nullo, e in caso contrario convertirlo in modo difensivo in qualunque tipo tu voglia, sia la var bar = new String(foo);
o var bar = "" + foo;
.
Puoi anche convertire un object String (insieme a qualsiasi altra cosa) in una primitiva String con toString
: var str = new String("foo"); typeof str; // object typeof str.toString(); // string
var str = new String("foo"); typeof str; // object typeof str.toString(); // string