You are here: irt.org | Articles | JavaScript | Object | Text Strings and String Objects [ previous next ]
Published on: Monday 30th June 1997 By: Martin Webb
This article will describe the differences between Text Strings and String Objects, and how to cope with these differences.
NOTE: the string object was introduced from JavaScript 1.1 onwards, therefore, if your browser supports either JavaScript 1.0 or JScript, some of the following examples, which have been coded to be browser friendly, will have some of the functionality restricted.
var variableName = "The early bird catches the worm.";
The previous line will create a variable called variableName, the contents of which are the text string:
Whereas the following line:
var objectName = New string("The worm should have stayed in bed.");
creates a string object called objectName, the contents of which are the text string:
For all intents and purposes these two items can be considered to be identical.
They can both use the methods and properties associated with the string object.
However, there is one major difference that can sometimes catch people out.
Consider the following example:
<SCRIPT LANGUAGE="JavaScript"><!-- var textString1 = "test"; var textString2 = "test"; if (textString1 == textString2) document.write("<BR>1. EQUAL"); else document.write("<BR>1. FALSE"); if (textString1.toString() == textString2.toString()) document.write("<BR>2. EQUAL"); else document.write("<BR>2. FALSE"); //--></SCRIPT><SCRIPT LANGUAGE="JavaScript1.1"><!-- var stringObject1 = new String("test"); var stringObject2 = new String("test"); if (stringObject1 == stringObject2) document.write("<BR>3. EQUAL"); else document.write("<BR>3. FALSE"); if (stringObject1.toString() == stringObject2.toString()) document.write("<BR>4. EQUAL"); else document.write("<BR>4. FALSE"); //--></SCRIPT>
Which when run produces the following output:
Note the use of JavaScript1.1 to restrict browsers supporting earlier versions of JavaScript from choking.
You may be surprised to learn that the third entry in the above example returns false, i.e. to similar string objects with identical contents when compared together are not equal.
Those who are familiar with Object Oriented languages will not be too surprised with this, as you are required to create your own comparison code when comparing objects.
As you can see there is an easy solution to this problem, as shown by the fourth entry, which uses the toString() method to convert the string object to a text string.
The reasoning behind the confusing nature of comparing string objects, may become more obvious if we tackle a more complicated object example.
The following code, defines an object array, and populates the array with two instances of the object:
<SCRIPT LANGUAGE="JavaScript"><!-- //This defines myObject: function myObject(name,email) { this.name = name; this.email = email; } //This populates an array with an instance of myObject: function populate_myObject(name,email) { contacts[index++] = new myObject(name,email); } //This constructs an array of myObjects, initially empty: var index = 0; var contacts = new Array(); //This creates an instance myObject: populate_myObject('Martin Webb','someone@somewhere.com'); //This creates another instance of myObject: populate_myObject('Martin Webb','sometwo@someone.com'); //This creates a third instance of myObject: populate_myObject('Martin Webb','somethree@someone.com'); if (contacts[0] == contacts[1]) document.write('<BR>contact 0 = contact 1'); else document.write('<BR>contact 0 <> contact 1'); if (contacts[1] == contacts[2]) document.write('<BR>contact 1 = contact 2'); else document.write('<BR>contact 1 <> contact 2'); //--></SCRIPT>
Which when run produces the following output:
You wouldn't necessarily expect complicated objects to be easily compared. However contact 0 is exactly the same as contact 1. Again this should be easy to solve using the toString() method - or should it?:
<SCRIPT LANGUAGE="JavaScript1.1"><!-- if (contacts[0].toString() == contacts[1].toString()) document.write('<BR>contact 0 = contact 1'); else document.write('<BR>contact 0 <> contact 1'); if (contacts[1].toString() == contacts[2].toString()) document.write('<BR>contact 1 = contact 2'); else document.write('<BR>contact 1 <> contact 2'); //--></SCRIPT>
Which when run produces the following output:
Aghhhh!!! Somethings gone wrong! Contact 1 shouldn't equal contact 2 as the email address in contact 2 was in lower case. What went wrong?
The following should clarify the problem:
document.write('<BR>'+contacts[0].toString()); document.write('<BR>'+contacts[1].toString()); document.write('<BR>'+contacts[2].toString());
Which when run produces the following output:
The toString() method didn't return the string text value of the object, but the object type of myObject, in this case 'object'.
This happens when objects do not have a defined toString() method. This is not the case with built in JavaScript objects such as Array, Boolean, Date, Function, Math, Number, String, as these already have a defined toString() method.
What we need to do is define our own toString() method for myObject:
<SCRIPT LANGUAGE="JavaScript1.1"><!-- function myObjectToString() { return this.name + ' ' + this.email; } myObject.prototype.toString = myObjectToString; document.write('<BR>'+contacts[0].toString()); document.write('<BR>'+contacts[1].toString()); document.write('<BR>'+contacts[2].toString()); if (contacts[0].toString() == contacts[1].toString()) document.write('<BR>contact 0 = contact 1'); else document.write('<BR>contact 0 <> contact 1'); if (contacts[1].toString() == contacts[2].toString()) document.write('<BR>contact 1 = contact 2'); else document.write('<BR>contact 1 <> contact 2'); //--></SCRIPT>
Which when run produces the following output:
What the previous scipt does, it to define a function called myObjectToString() which returns the name and email properties of the current object separated with a space character.
This function is then associated with myObject as the toString() method using the prototype method.
Now when the toString() method is used myObjectToString() returns a text string, which is then correctly compared.
We can now make further enhancements to this. For example, the email addresses in contacts 1 and 2, are the same if not identical. If these were stored in a simple database, we would want any comparison routine to correctly identify them as equal, even if the case is different.
This can be achieved by replacing the myObjectToString() function with another:
<SCRIPT LANGUAGE="JavaScript1.1"><!-- function myObjectCompareToString() { return this.name.toLowerCase() + ' ' + this.email.toLowerCase(); } myObject.prototype.toString = myObjectCompareToString; document.write('<BR>'+contacts[0].toString()); document.write('<BR>'+contacts[1].toString()); document.write('<BR>'+contacts[2].toString()); if (contacts[0].toString() == contacts[1].toString()) document.write('<BR>contact 0 = contact 1'); else document.write('<BR>contact 0 <> contact 1'); if (contacts[1].toString() == contacts[2].toString()) document.write('<BR>contact 1 = contact 2'); else document.write('<BR>contact 1 <> contact 2'); //--></SCRIPT>
Which when run produces the following output:
This uses a new function myObjectCompareToString which is replaced as the myObject toString method. The myObjectCompareToString function uses the toLowerCase() method to ensure that the case of the name and email properties do not effect the outcome of the comparison.
This also illustrates another feature - the toString method associated with an object can be altered as and when required, just by reassociating it with another function by using the protocol method.
Arrays, Object Arrays and Sorting