Page 1 of 4
Patterns & Practice
- Active Logic, Truthy and Falsey*
- Self Modifying Code*
- Lambda expressions
- Meta Programming Using Proxy
- The Function Approach To Programming
*= recently revised.
Sometimes it is good for an object to have a value, or even more than one value. For example, suppose you have an object that represents an item in an order. The object may have a number of additional properties and methods.
However if you consider the primary property of an item to be its price you might want to write expressions such as:
Similarly you might consider the item's name to be its primary string property and you might want to write statements like:
You might argue that this isn't a good example of using default values and that it would be better to use the full property names. However, there are examples where it is natural for the values stored in an object to take part in arithmetic, logical or string expressions and in these cases not to have the ability to define default values.
So how do you define a default value?
The answer is surprisingly simple.
When an object is involved in an expression the valueOf method is called which returns a numeric or Boolean value. The numeric or Boolean value is further type converted to make the expression work. If the object is part of an expression where a string would be required then toString is called.
So far this is nothing new and it just gives rise to the type conversion rules that you should know about. However you can define your own valueOf and toString methods and these can be used to deliver custom default values.
Following this you can write:
and the result will be 200.
If an object has a valueOf function defined then it can be used to supply a value whenever the object is used in an expression and a numeric value is required.
What do you think you get if you write the simpler:
The answer is not that result is set to the simple value 20. This is an object assignment and result is set to another reference to myObject. This can be confusing because if you now try something like:
you will still see 200 stored in a because result refers to the same object as myObject and so valueOf is called to return 20 in the expression. In other words result behaves as if it was 20 in an expression just as myObject does. However, if anything changes myObject so that it returns some other value, then a will not equal 200 after the expression.
It also works if a Boolean value is required. For example, if you change the definition of myObject to:
then you can write things like
which evaluates to false.
At this point you might be wondering how you can work out what to return from valueOf when you can't know how it will be used in an expression. For example, what if you you use the Boolean valued myObject in an arithmetic expression?
This is very flexible, but you should always return a value that is appropriate for the meaning of the object you are working with.