JavaScript Jems - Functions Are Objects
Written by Mike James   
Wednesday, 08 November 2023
Article Index
JavaScript Jems - Functions Are Objects
Passing Functions
Function Properties

Function Properties

As a function is an object that just happens to be associated with some code that you can execute, a function can have properties. This is perhaps the strangest thing about function objects from the point of view of a programmer who is familiar with functions in other languages. In fact, it is so strange you very rarely see a function property actually being made use of in code.

For example:

var myAdd=function(a){
                      var result=a+myAdd.myValue;
                      return result;
                     }

You can see the general idea. The myValue variable is a property of the object myAdd which just happens to be a function. This looks wrong because the code of the function is using myAdd and myAdd.myValue before they are defined. If you think about it, this is not the case because the function only uses them when it is run, i.e. when it is invoked.

What matters is that myAdd and myValue are defined when the function is called:

myAdd.myValue=3;
alert(myAdd(4));

You can see that when myAdd is called, myAdd references the function object and myAdd.myValue is defined and now has a value. Again, this is another aspect of a function object living longer than its time executing.

It is also clear that myValue is playing the same role as in the previous example in providing the value the function adds to its parameter. In the previous case the value was provided from the outside world via a parameter that was included in a closure. In this case the value is provided as a property.

What is the difference? The key difference is that the property is public and available both while the function isn’t running and when it is. The closure variable is only available to the function's code and hence only while it is running. This means you can change and access the property at any time, but the closure was set by the outside world just once, via the parameter.

You can use function properties for all sorts of of tasks, for example, error and status reporting:

var mySum=function(a){
                 var result=a*2;
                 mySum.error=”something went wrong”;
                 return result;
                 }
mySum(3);
alert(mySum.error);

Of course, in a real case you would have a conditional that set the property only when an error occurred. Also notice that you don’t have to set up the error property before calling the function, but it is a good idea to do so. The dynamic nature of JavaScript’s objects lets you add a property at any time. The downside is that if you try to use the error property before the function has been executed you will get an error. Hence it is a good idea to initialize it when the function object is being created.

Function properties are not limited to simple values – they can be objects in their own right. In particular, they can be functions. This is another idea that causes difficulties if you are still thinking about functions as found in other languages.

What could function properties be useful for? Well, what about initialization:

var mySum=function(a){
                 var result=a*2;
	         mySum.error=”something went wrong”;
                 return result;
                     }
mySum.init=function(){
                       mySum.error=””;
                     }
mySum.init();
mySum(3);
alert(mySum.error);

The only problem with this approach is that you have to remember to call the init function.

Another, and potentially more serious problem, is due to the fact that functions, indeed all objects in JavaScript, do not have fixed names. This is explained in detail in Jem 5.

If we assign something to mySum then the code in the function will fail because the new object isn’t a function with a property called error. For example:

var mySumNew=mySum;
mySum={};
mySumNew(2);

fails because mySumNew might reference the same function object as mySum did initially, but within the code mySum now references an empty object and there is no mySum.error.

Using the alternative form of function declaration:

function mySum(){
                  mySum.error=””;
                }

is a sort of protection in that many JavaScript programmers think that now the name mySum is allocated to the function and this cannot be changed. It can and you get exactly the same problem, but as most JavaScript programmers believe that a function’s name cannot change it is less likely they will try to.

The only real solution to this naming, or self-reference, problem is to create all function objects using a function factory:

var myFuncFactory = function () {
                      var self = function () {
                                   return self.myValue;
                                 };
                      self.myValue=0;
                      self.error=””;
                      return self;
                    };

Notice that now you can create mySum using:

var mySum= myFunctionFactory();

and the code will work even if you change what mySum references because the code in the function doesn’t make use of it. Instead it makes use of self, which, as it is part of the execution context of the function when it is created, it is part of the closure. This means that only the code in the function can access it and there is no chance of it being changed by accident.

This is why functions being objects that have some code associated with them is a jem.

Now available as a book from your local Amazon.

JavaScript Jems:
The Amazing Parts

kindlecover

Contents

<ASIN:1871962579>

<ASIN:1871962560>

<ASIN:1871962501>

<ASIN:1871962528>

espbook

 

Comments




or email your comment to: comments@i-programmer.info

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.



Last Updated ( Wednesday, 08 November 2023 )