Just JavaScript - The Object Expression
Written by Ian Elliot   
Thursday, 12 June 2014
Article Index
Just JavaScript - The Object Expression
String Values
Comparison Operators
Functions In Expressions

 

Answers to quiz

  1. "3345" 
    Reason: All the + operators have the same priority and are hence evaluated from left to right. The first operator is 1+2 and so the answer is Number 3. The second operator is now 3+"3" and as one of the operands is a String the first 3 is converted to a String and the result is "33". The third operator is now "33"+4 and by the same reasoning this is concatenation and the result is "334". The final operator is "334"+4 and again this is concatenation and the result is "3344". 

  2. 7
    Reason: * has a higher priority than + so the first operator is "2"*3 and after "2".valueOf() the result is 6. The second operator is now 1+6 so the result is Number 7.

  3. "416"
    Reason: * has the higher priority so the first operator is "2"*3 and after "2".valueOf() the result is 6. But now the + operators have equal priority and the expression to evaluate is "4"+1+6. The first operator is "4"+1 which evaluates to "41". The final operator is "41"+6 which evaluates to "416".

  4. "122"
    Reason: The first operation is concatenation and hence so is the second.

  5. "14"
    Reason: Despite this looking like the previous example,  the expression on the right is evaluated first and then the a+ operation is performed. That is, it is equivalent to a=a+(2+2); or "1"+4.

 

Banner

Every object has a string value

Just as the valueOf method gives every object a value, the toString method does the same sort of thing for strings.

  • Every object has a toString method that can be used to supply a String representation of the object. 

  • You can define your own toString method or you can accept the use of the default. 

  • You can provide a toString method to a custom object as in the case of the valueOf method. 

For example:

var myObject={}; 
myObject.valueOf=function(){return 1;}; 
myObject.toString=function(){return "myString";};

Now we have a custom object which has a value and a String representation. 

As in the case of valueOf, you don't have to return a String object as the result of a toString method, but not to do so would be misleading in the extreme. 

So when is toString used in an expression?

There are two ways that toString can be invoked during the evaluation of an expression. 

The first is to get a primitive value for the object. 

Put simply, if the expression evaluator fails to get a primitive object from valueOf it will try toString to get one. 

That is, it first uses the valueOf method. If this returns a primitive value then it stops. If this returns a general object the evaluator next tries the toString method to see if this can provide a primitive value. If this works the value is used in the expression; if it doesn't then you get a runtime error

Cannot convert object to primitive value

To see this in action try:

var myObject1={};
myObject1.valueOf=function(){return {};}; myObject1.toString=function(){return {};}; a=1+myObject1;

Notice that in this case both methods return an empty object, which isn't a primitive value. 

Notice that toString can return a Number object and this will work:

myObject1.valueOf=function(){return {};}; myObject1.toString=function(){return 1;};
a=1+myObject1;

This doesn't throw a runtime error and it results in 2 stored in a. 

The evaluator dosn't care about what type of primitive object it gets from valueOf or toString - as long as it is a primitive object.

The second way the toString method can be called is if the primitive value obtained earlier is the wrong sort of primitive. 

For example, consider concatenation. You might think that if one of the operands in the expression was a String:

a=myObject1+"1";

then the toString method would be called to convert the other object to a String. 

This isn't what happens.

What happens is the same two steps - first valueOf is called and if it doesn't provide a primitive value toString is called. 

At this point we assume we have a primitive value, pv, ready to be used in the expression. 

If the expression turns out to be concatenation, because of the other operand being a String, then the toString method is called on the primitive value, i.e. pv.toString() is used in the expression. The original object's toString method isn't used.

This is because the object's value is more important than its String representations. 

For example:

var myObject1={};
myObject1.valueOf=function(){return 1;};
myObject1.toString=function(){return "One";};

followed by:

"1"+myObject1;

is "11" because valueOf return 1 which is a primitive value and then 1.toString() is called to give "1" which is used in the concatenation. Object1's toString method doesn't get used. 

Also notice that it doesn't matter which of the two methods returns the primitive value. 

The same sort of thing happens if your custom object returns a String primitive value when the expression needs a Number. In this case the primitive value's valueOf is called in an attempt to obtain a Number primitive. If this doesn't work the result of the expression is NaN - Not A Number.

Recap

Putting all this together:

  1. JavaScript expressions are evaluated in order of precedence and then left-to-right (in most cases) for equal precedence operators. 

  2. All objects involved in an expression are first converted to a value using valueOf.

  3. If any valueOf method doesn't return a primitive value, i.e. a String or a Number, then the toString method is used to get a primitive value, i.e. a String or a Number. 

  4. If neither valueOf or toString returns a primitive value then there is a runtime error.

  5. If the primitive value obtained in step 2 or 3 is of the wrong type for the operator, then toString or valueOf is called on the primitive type to convert it.

 

Built-in objects and type conversion

Built-in objects like String have a predefined valueOf method that returns sensible values for the object.

What is a sensible value for a String?  

The obvious answer is a String. 

What is the sensible value for a Number?

The obvious answer is a Number.

So far so good. 

In both cases valueOf returns the same primitive type as the original object. In a sense a Number and a String are their own object values. 

What happens if a Number is involved in an expression that requires a String?

The answer is that its toString method is called. 

What happens if a Number is involved in an expression that requires a string?

In this case the internal toNumber method is called. You can't make use of the toNumber method but it is automatically called to convert a String to a Number when required. 

Consider, for example:

var a=new Number(2); 
var num=new String("123");
a=a*num; 
alert(a);

In this case when the String object is used in the expression a*num then its default valueOf method is called automatically and it returns a primitive string. Next, internally, the toNumber function is called to convert the value to a number.  If the string cannot be converted then the result is NaN - Not a Number. 

<ASIN:0596805527>

<ASIN:193398869X>

<ASIN:0137054890>

<ASIN:1449381871>

<ASIN:1430230541>



Last Updated ( Sunday, 10 May 2015 )