What are the use cases for doing new String(\"already a string\")
?
What\'s the whole point of it?
String
objects can have properties, while string primitives can not:
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
And String
objects can be inherited from, while string primitives can not:
var foo=Object.create(aStringObject);
var bar=Object.create(aStringPrimitive); //--> throws a TypeError
String
objects are can only be equal to themselves, not other String
objects with the same value, while primitives with the same value are considered equal:
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
You could implement overloading-like behavior:
function overloadedLikeFunction(anArgument){
if(anArgument instanceof String){
//do something with a String object
}
else if(typeof anArgument=="string"){
//do something with a string primitive
}
}
Or specify argument purpose:
function aConstructorWithOptionalArugments(){
this.stringObjectProperty=new String("Default stringObjectProperty value");
this.stringPrimitiveProperty="Default stringPrimitiveProperty value";
for(var argument==0;argument<arguments.length;argument++){
if(arguments[argument] instanceof String)
this.stringObjectProperty=arguments[argument];
if(typeof arguments[argument]=="string")
this.stringPrimitiveProperty=arguments[argument];
}
}
Or track objects:
var defaultStringValue=new String("default value");
var stringValue=defaultStringValue;
var input=document.getElementById("textinput") //assumes there is an text <input> 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 <input>
return stringValue!=defaultStringValue;
}
The existence of String
objects and string primitives effectively gives you two string "types" in Javascript with different behaviors and, consequently, uses. This goes for Boolean
and Number
objects and their respective primitives too.
Beware, however, of passing string (or other) primitives as the value of this
when using the function methods bind()
, call()
and apply()
, as the value will be converted to a String
object (or a Boolean
or a Number
object, depending on the primitive) before being used as 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;
And unexpected/counter-intuitive return types:
var aStringObject=new String("I'm a String object");
console.log(typeof aStringObject); //--> object
aStringObject=aStringObject.toUpperCase();
console.log(typeof aStringObject); //--> string
In most cases you work alone and can control yourself, or on a team and there is a team guideline, or can see the code you're working with, so it shouldn't be a problem. But you can always be extra safe:
var obj = new String("something");
typeof obj; // "object"
obj = ""+obj;
typeof obj; // "string"
Update
Haven't though much about the implications of this, although it seems to work:
var obj = new String("something"), obj2 = "something else";
obj.constructor === String; // true
obj2.constructor === String; // true
Of course, you should check if the object has a constructor (i.e. if it is an object).
So you could have:
isString(obj) {
return typeof obj === "string" || typeof obj === "object" && obj.constructor === String;
}
Although I suggest you just use typeof and "string", a user should know to pass through a normal string literal.
I should note this method is probably susceptible to someone creating an object and setting it's constructor to be String
(which would indeed be completely obscure), even though it isn't a string...
Javascript creators created wrappers for basic types like string or int just to make it similar to java. Unfortunately, if someome makes new String("x") the type of the element will be "object" and not "string".
var j = new String("x"); j === "x" //false j == "x" //true