Monday, November 26, 2007

JavaScript String :: Primitive or Object?

A colleague and I were chatting about JavaScript strings and he noted that they're not objects. He's half right.

JavaScript strings are primitives much like numbers and booleans, but they can also be objects ( like Numbers and Booleans ).

You can create a String object ( I've capitalized String ) by calling it's constructor --

var aStr = new String("I'm a String object");

You can also create a string like this without calling the constructor ( that is without the "new" operator ) --

var aStr = String("I'm a string primitive");

This is the same as calling --

var aStr = "I'm a string primitive";

which results in a string primitive or as I typically call it, a string constant or a string literal.

Typically, you don't have to worry about whether you're dealing with a string primitive or a String object because JavaScript automatically converts the primitive to a String object.

So, you can do things like getting the length of a string primitive --

var myStr = "I'm a string primitive";
alert(myStr.length);

or calling methods --

alert("string primitive".substring(0,7));

All this means is that you can access any property found in the String object from a primitive.

The difference between a primitive and a String object is when you're adding functionality to a String. You can't do it to primitives.

So, if you wanted to add a function to reverse the characters in a string, you'd do something like this by adding it to the String object's prototype property --

String.prototype.reverseString = function() {
var len = this.length;
var result = "";
var strArray = [];
var ct = 0;
for (var i=len-1;i>=0;i--) {
strArray[ct++] = this.charAt(i);
}
return strArray.join("");
}

If you called it,

"cola".reverseString();

it's the same as

var cola = new String("cola");
cola.reverseString();

Though you've added the method to the String object, you can use it with a primitive!

Note that JavaScript strings are immutable ( you can't change them ). This is why the method reverseString returns a new string from the array.

All of this is pretty obvious, but I thought I'd share my thoughts.
Enjoy!

3 comments:

Klay said...

skypoet,

Another diference from String Objects and literals is:

var stringObjec = new String('string object');
stringObjec.newproperty = 'new property';
alert(stringObjec.newproperty);
//will display 'new property'

u can do it with a String object, but cant with a primitive one.

var literalString = "i'm a literal string";
literalString.newproperty = 'new property';
alert(literalString.newproperty);
//will display 'undefined'

skypoet said...

Nice point Klay. You're right. You can add properties to object, but not to string primitives.

Anonymous said...

Tere are also differences with 'typeof' and 'instanceof' operators on string objects and string primitives. Some of them are pretty unexpected. For example, typeof new String('test') returns false.

javascript:var str = 'test'; var obj = new String('test'); alert("typeof str = " + (typeof str) + "; str instanceof Object = " + (str instanceof Object) + "; str instanceof String = " + (str instanceof String) + "\n" + "typeof obj = " + (typeof obj) + "; obj instanceof Object = " + (obj instanceof Object) + "; obj instanceof String = " + (obj instanceof String));

Would yield:

typeof str = string; str instanceof Object = false; str instanceof String = false
typeof obj = object; obj instanceof Object = true; obj instanceof String = true