Another common "string context" occurs with the + operator. When + is used with numeric operands, it adds them. When it is used with string operands, however, it concatenates them. When one operand is a string, and one is a nonstring, the nonstring operand will first be converted to a string and then the two strings will be concatenated:
x = 1 + 2; // yields 3 x = 'hello' + 'world'; // yields 'helloworld' x = 1 + '2'; // yields '12' x = true + '3'; // yields 'true3'
Actually, the + operator even works when both operands are of object type: the operands are converted to strings and concatenated. When one operands is an object, and the other is neither an object nor a string, both operands are converted to strings and concatenated:
x = window + 1; // yields '[object Window]1' x = window + top; // yields '[object Window][object Window]' x = window + true; // yields '[object Window]true'
The paragraphs above have described the "string contexts" in which values are converted to strings. Here is exactly how that conversion is performed:
For example, the following lines of code contain non-numeric values in numeric contexts, and cause automatic conversion to occur:
Math.sin("1.45"); // String "1.45" converted to number 1.45 done = sum > "10" // String "10" converted to number 10 sum = sum + true; // Boolean value true converted to number 1 total = total - "3"; // String "3" converted to number 3
total = total + "3"
For example, the following lines of code use the integer i, the string s, and the object o in boolean contexts, and cause those values to be converted to boolean values:
for(i = 10; i; i--) document.write(messages[i]); response = s?"yes":"no"; if (o) sum += o.value;
len = s.length; document.write(s.bold()); t = s.substring(2,4); a = s.split(",");
The rules for automatic conversions to objects are particularly straightforward:
s = new String("hello"); s = new Object("hello");
The second reason why conversion to objects is often transparent to programmers is that each of the String, Number, Boolean, and Function objects have toString() methods that are invoked when they are used in a string context, and have valueOf() methods that are invoked when they are used in numeric, boolean, or function contexts. Because the data conversion is so completely automatic, it can be difficult to even distinguish between a value and its corresponding object. The typeof operator provides one way to distinguish primitive values from objects. When invoked on a primitive value, typeof will return one of the strings "string", "number", "boolean", and "function". When invoked on the corresponding object, however, it will return "object":
typeof "hello" // returns "string" typeof new String("hello") // returns "object"
While many of the automatic data conversions explained in the subsections above are intuitive, there are so many of them that it can be difficult to keep them all straight. Table 9.1 summarizes each of the possible conversions.