|Written by Ian Elliot|
|Thursday, 15 May 2014|
Page 1 of 3
There is a newer version of the draft of the book here.
Objects with function properties
As we discovered in Chapter 1, an object is a set of properties with object values. As a function is nothing more than a Function object there is no reason why a function cannot be a property of another object.
creates a new object with a single property myFunction which is a Function object with code body:
The only problem with defining Function properties is how to format them on the page to make the code clear. Most use something like:
To execute the code body of the Function property you simply need a reference to the Function object i.e.
and the evocation operator () which gives:
And it is always worth remembering the difference between the two.
If there were parameters they would be included in the usual way between the brackets.
You can also write:
as the reference to the Function object and
as the evaluation of the function body. In this form it looks a lot less like a traditional function call but there is nothing new here either.
Why would you use an object with Function properties?
An object is a good was to gather together functions that do the same sort of job. For example the built in Math object provides a place to group mathematical functions like sin, cos and so on. To use such a function you have to write something like:
In this case it might seem inconvenient to have to write the full "dotted" reference to the Function object but in general it is useful to be able to separate the name applied to this function and any other function which might happen to have the same name.
In other words using Functions within objects is a way of avoiding name collisions.
When ever you are working on a large program trying to find unique names for things becomes increasingly difficult as the program gets bigger. You generally end up applying a good name to the first function or variable of a particular type such as totalHours only later to have to use something less meaningful such as tHours to avoid the name collision with the first function or variable.
In other languages name collisions are made less of a problem by they use of "namespaces" which assign multipart names for things without having to get involved in creating objects necessarily. Usually the first part of the name is derived by the IDE or the language conventions unless there is a name collision when you have to provide a fully qualified name.
Of course to avoid a name collision with someone else's sin function you would be well advised to put your new function within a suitable object - e.g. myMathFunctions. Of course the trick here is finding a name for your "namespace" object that is going to be unique and so avoid an initial name collision. This is the reason why some programs make use of a domain name for the object e.g. iprogrammerinfo but this is usually necessary and makes things look complicated.
You can also make use of multiple nested object to create a nested namespace. So you could have
and so on.
You can even simplify naming where required by assigning the fully qualified name to something shorter. For example:
and following this statement you can just write
To labour the point for one final time notice that Math.sin isn't a function it is a reference to a Function object that is one of the properties of the Math object.
Functions become methods
You might at this point be thinking that we have just looked at how an object can have methods - this isn't so.
An object can have Functions as properties and this is useful but a simple Function object even when assigned as a property isn't a method.
The reason is that a method is something that an object does to itself. That is the code of a method doesn't just do something external like compute a sin or a square root. A method is something that you ask an object to do like print itself or use its data properties to make a connection to a secure server or copy itself.
A method is an action that an object performs which involves other parts of the object.
Yes the definition is vague and you could argue that a collection of math functions were methods but the best test of whether a function is a method is to ask if it would work in the same way if you removed it from its object. That is Math.sin(0.5) can be considered to work in the same way and do the same job as sin(0.5).
Now consider a something like:
which returns the size of the object computed in some way appropriate to the object. Ask yourself what does:
mean when it is removed from the object? Clearly by our definition size() is a method as it needs to know the object it is a property of to do its job.
At this point you may object slightly and point out that you can convert size the method into size the function by providing it with a parameter. That is
is the same as:
both of which return the size of the object in some appropriate way.
Yes absolutely right and it's not really an objection.
This swapping of object property to parameter is the key to the difference between a method and a pure function.
For a function to be a method it has to accept the object it belongs to as some sort of default parameter - and this is where "this" comes in.
Consider for a moment a simple example of a function as an object property:
You can see what it is trying to do.
The mySize function is to return the size of the object as given by the object's mySize property.
If you try this out using say:
you will discover that you get an error message telling you that mySize is not defined. This is perfectly reasonable as mySize in the function's body either is a reference to a local or a global variable and clearly neither exist.
To make the function into a proper working method we have to make mySize reference the property of the object called mySize.
We can do this very easily and in the obvious, in fact far too obvious way using:
This works but it isn't a good way of achieving the result we are looking for. Using the name of the object in a method isn't a good idea at all.
The reason is that myObject isn't the name of the object in question. It just happens to be a variable that references the object at the moment.
All that happens here is that we set another variable to reference the object and use the original variable for something else i.e. to store an empty object.
Now the program still runs but the size is returned as undefined.
You can't make use of the object's name in a method because the object doesn't have a name only variables that reference it and these can change at any time.
|Last Updated ( Wednesday, 13 September 2017 )|