Naked JavaScript - Constructor Functions
Join the DZone community and get the full member experience.
Join For Free
In the part 4 of the series - Naked Javascript, we are going to take a deeper look at Functions in Javscript and explore its twisted syntax and various implications. In the previous article,
we learnt about the different ways in which you can invoke functions.
In this part, we examine the stuff that is responsible for creating
functions in JavaScript.
Functions in JavaScript are fantastic. Not only are they used to execute
functionality, but they are also used to create other objects and
functions(Yes, you read that right). Functions are means by which you
implement a very significant feature of the language - inheritance. We
will be talking about the details of inheritance later. For now, lets
continue exploring functions.
Like all amazing and awesome things in the world, when you talk about
functions in Javascript, there is more to it than meets the eye. The
real way to figure out what more is out there is by firing up your
browser console and dissecting it bit by bit.
Lets first try to answer a very basic quesion. What exactly is a
function?
Well, a function is nothing but a Javascript object. Yes I know that I
have said that numerous times in the previous parts of the series, but
believe me when I say that it is impossible to stress this point any
less.
However, functions are objects with a few special features that makes
them stand out from ordinary objects. In order to understand what
functions are you first need to know who creates functions.
In javascript, in order to create objects, all you need to do, is define
a constructor. Unlike other programming languages(e.g. Java), you dont
need any special wrapper around a function, i.e. your constructor does
not have to defined inside of a class. A constructor is just an ordinary
function. For example
function Employee(){ //blah blah console.log('Employee function'); };
This is a simple constructor function. There is nothing special about
this function. The only thing that is different here is the fact that we
followed a different naming convention by capitalizing the first
alphabet of the function name. This convention is recommended and
important when you are declaring constructor functions because it lets
others differentiate between ordinary functions and functions that are
designed with the intention of be used as a constructor function.
Now this function does not seem to be doing anything special. But in
Javascript, you can do something totally strange. You can create
instances of functions. For example, once you have declared a employee
constructor function like the one above, you can do somethig like this.
function Employee(){ console.log('Employee function'); }; var emp1 = new Employee();
The syntax is both befuddling and amusing. Lets try to understand the
what exactly is happening under the hood here when we invoke a function
along with a new operator.
This syntax of invoking functions that are meant to be constructor
functions was designed to appeal to Java programmers. When you invoke a
function using the 'new' keyword, the runtime creates an empty object
and passes that object to the function. That object then becomes the
value of the 'this' keyword inside the function. I will be covering the
'this' keyword in JavaScript in details in a later part of this series.
But for now, assume that when invoked using the 'new' keyword, the
'this' inside the function behaves similar to the 'this' keyword used in
Java. Once the function finishes its execution, the function
automatically returns a reference to the 'this' even though you did you
explicitly write a return statement at the end of the function. Note
that had you invoked the Employee() function without the 'new' keyword,
no new object would have been created, and our Employee function would
have returned nothing without an explicit return statement.
After the function execution, the variable emp1 now points to the newly
created object. You can think of this object to be an instance of the
function. I say so because if you try to execute 'emp1 instanceof
Employee', it returns true. The 'instanceof' keyword is an easy way to
determine the name of the function responsible for constructing an
object.
Not only that, every object has access to a property called
'constructor' that tells you about the constructor of that object. For
example, you could do something like this.
function Employee(){ console.log('Executing Employee function'); }; var emp1 = new Employee(); var dummy = {}; console.log(dummy.constructor); console.log(emp1.constructor);
When you run it on chrome, you would be able to see the following lines on the console.
Executing Employee function function Object() { [native code] } function Employee(){ console.log('Executing Employee function'); }
The first line is the normal console.log that was executed when you
created a new function object. Thats not much of a mystery anyways. But
then, you see another line that says "function Object() { [native code]
}". This comes from the log of dummy.constructor. And then in the next
line, you see all the dirty little details of our own 'Employee'
function. (This point should give you ideas!).
Ok, now that we understand how to create a custom constructor function
and create instances using the constructor function, lets have some more
fun with functions.
Remember when I said that, that functions are objects too?. And this
directly implies that there has to be some constructor function that
constructs functions(Tongue twister alert!). Dare to explore? Yes sir!
function Employee(){ console.log('Executing Employee function'); }; console.log(Employee.constructor);
Turns out that there is a function called "Function" that does the magic
of constructing functions for us(This should be your Eureka moment,
ryt!! Or, maybe its just me).
So we have a function that creates other functions and it is aptly a
function called - "Function". Also note that the naming convention for a
constructor function is being followed here. Hey, guess what? Even
anonymous functions have the same constructor. Of course they do, since
they are functions too(Love that rhyme, dont you?).
console.log((function noname(){}).constructor);
Well, am gonna let curiosity kill the cat and find out who makes the
Function function too, because hey, even thats an object, ryt?
console.log(Function.constructor);
It seems that the Function function creates itself. (Ok, now the cat's dead ).
Now that you know that a function creates a function, this gives you the ability to formulate a new syntax to create functions.
var dynamicFunction = new Function();
However, the function that we just created is not of much use in this
way, because we don't have a function body. But hey ho!, you can create
your function with full fledged parameters and the function body as
shown in the example below.
var nowThisIsWeirdButCool = new Function('p1','p2','console.log("Stripping "+p2+" "+p1)'); nowThisIsWeirdButCool('Naked','Javascript');
As you can see, this is a pretty convoluted way of defining functions,
but still, it certainly is one of the ways in which you can choose to
create functions in JavaScript. Amazing right? But, note that is a
really BAD BAD BAD way to create functions because functions created
using this technique make use of the sacred JavaScript function 'eval'
in order to evaluate the definition of the function body provided as a
string parameter at runtime. The use of the eval() function is
considered to be evil. ( Need I say that the two words even rhyme to a
certain extent. See my point?).
To conclude, this post uncovered a few more aspects of functions in
JavaScript. As I said before, functions are the building blocks of so
many things in JavaScript, that is is quite impossible to talk about
anything in JavaScript without talking about functions and their various
idiosyncracies.
However, this is all that I have for this part of the series. There's more coming. Stay tuned for the next!
JavaScript
Object (computer science)
Published at DZone with permission of Ryan Sukale. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments