Page 1 of 2 Functions are objects, but we tend to forget that they are. Just like all objects in JavaScript, functions are anonymous and unlike other languages don't have immutable names. This isn't a huge problem,. but how can you write a Function that references its own properties without a fixed name? We need the self reference pattern.
This is an extract from the book Just JavaScript by Ian Elliot.
Buy Now: from your local Amazon
Just JavaScript An Idiomatic Approach
A Radical Look At JavaScript
Most books on JavaScript either compare it to the better known class based languages such as Java or C++ and even go on to show you how to make it look like the one of these.
Just JavaScript is an experiment in telling JavaScript's story "just as it is" without trying to apologise for its lack of class or some other feature. The broad features of the story are very clear but some of the small details may need working out along the way - hence the use of the term "experiment". Read on, but don't assume that you are just reading an account of Java, C++ or C# translated to JavaScript - you need to think about things in a new way.
Just JavaScript is a radical look at the language without apologies.
Contents
- JavaScript – Essentially Different
- In The Beginning Was The Object
- Real World Objects
- The Function Object
Extract - The Function Object Extract - Function Object Self Reference
- The Object Expression
- Function Scope, Lifetime & Closure
Extract Scope, Lifetime & Closure Extract Execution Context ***NEW!
- Parameters, Returns and Destructuring
Extract - Parameters, and Destructuring
- How Functions Become Methods
- Object Construction
Extract: - Object Factories
- The Prototype
Extract - ES2015 Class and Extends
- Inheritance and Type
- The Search For Type
- Property Checking
Buy Now: from your local Amazon
Also by Ian Elliot JavaScript Async: Events, Callbacks, Promises and Async Await Just jQuery: The Core UI Just jQuery: Events, Async & AJAX
<ASIN:1871962579>
<ASIN:1871962560>
<ASIN:1871962501>
<ASIN:1871962528>
Function Objects Are Anonymous
As has already been explained, in earlier chapters, all objects in JavaScript are nameless, or anonymous if you like, and Function objects are no different. However in most other languages function are tied tightly to a single name and this makes JavaScript different. This name usually indicates what the function does. For example you might define the max function which finds and returns the maximum of two numeric values and in many languages this would be the immutable name of the function.
In JavaScript however there are no immutable object names and in particular no immutable Function names.
In JavaScript you can create a max function in any of three ways. Using a constructor:
var max = Function("a", "b", "if(a>b)return a;return b;");
Using a function expression
var max = function (a, b) { if (a > b)
return a; return b; };
Using a function statement:
function max(a, b) { if (a > b)
return a; return b;
};
In each case you can call the function in the usual way:
alert(max(3,4));
but you can also make things slightly more difficult by creating a new reference to the function:
var min=max;
alert(min(3,4));
Now you are calling the same function but using the “name” min.
Many programmers are happy that the first two function definitions work like this but are surprised that the function expression doesn’t confer a fixed name on the function. Notice that the variable max can be assigned a new value so removing even the possibility of calling the function using the “name” max.
For example:
max=0;
max(2,3);
Results in a “not a function” error.
Although function names assigned using Function statements are often regarded as the assigned names of the Function object they are just as much variable references to the object as in the case of the constructor or the Function expression. They tend not to be modified but only because this is the way programmers think about them.
It is worth mentioning that ES2015 introduced the Function.name property which records the name given to the function when it is first created. If you try:
alert(max.name);
you will see anonymous for the constructor and max for the Function expression and Function statement. The name property cannot be changed by assignment but you can use defineProperty to change it. As the name property is a String you can’t use it to directly call the function and hence it isn’t as useful as you might expect.
Function Properties
The final fundamental characteristic of a Function object which makes JavaScript function different is that they can have properties as well as code.
You can create properties of a function object just like any other object. As long as you are fully aware that a function in JavaScript is an object then this is not a surprise but this is one of the most overlooked features of JavaScript. In practice you rarely see functions with properties.
For example:
var myFunction= function(a,b){ var ans=a+b; return ans;
};
myFunction.myConstant=3.14159;
alert(myFunction.myConstant);
There is nothing new here. The variable myFunction references a Function object and we can dynamically create a new property myConstant. Later we can access the properties value in the usual way.
What is new is the possibility of referencing a property of the function within the code of the function.
For example:
var myFunction= function(a,b){ var ans=a+b; return ans*myFunction.myConstant; };
Now at this point you might be worried by the idea of using myFunction.myConstant before the function has been fully declared and perhaps even well before the property has been created. Of course you are not using myFunction.myConstant before the function has been fully declared because the property is only accessed when the function is evaluated.
That is the code for the function is stored in the Function object and as long as the code makes sense at the time it executed everything works:
myFunction.myConstant=3.14159;
alert(myFunction(1,0));
At the point the function is called myFunction and myFunction.myConstant both exist and are fully defined.
There is just one problem with this approach.
What if myFunction is redefined?
As already explaind Function objects are as anonymous as any JavaScript Object and they do not have fixed names just references in variables. That is myFunction is just a standard variable and not the fixed name of a function and so it can be assigned to in the usual way. In this case myFunction.myConstant will reference a property on some other object when the function is executed.
For now the most common solution to the problem is to use a Function statement and pretend that the function name you assign isn’t something that can be changed – it can but few make use of this in practice.
For example:
function myFunction(a,b){ var ans=a+b;
return ans*myFunction.myConstant; }; myFunction.myConstant=3.14159;
alert(myFunction(1,0));
works perfectly and few programmers would think to redefine myFunction. Of course if myFunction is reused then things don’t work:
var myFunction2=myFunction;
myFunction=0;
alert(myFunction2(1,0);
In this case the call using myFunction2 works in that it references the same Function object as myFunction did but the function no longer works because it uses myFunction to reference itself.
The problem is that there is no elementary way that a Function object can make a “self” reference. You can’t use this because this is the call context and in this case it is set to window – the global object.
The simplest solution is to use the callee property of the arguments object which is available to every function.
|