Just the weekly tutorials.

The life of JavaScript function properties

Everyone knows what functions are. We can define and call them. In JavaScript almost everything is an object. Even strings can be constructed by creating a new object (vs. just defined with the literal string value:)

var str = new String("Hello");

Functions are objects too. Objects of type Function. Therefore we can create them in this rather peculiar way:

var add_two_numbers = new Function("arg1", "arg2", "return arg1 + arg2;");

This would be the exact equivalent to doing the following:

function add_two_numbers(arg1, arg2) { return arg1+arg2 }

What's next -- now that we created a function?

Accessing function properties

It's amazing what kind of tools JavaScript offers us when it comes to working with functions. For the most part you will probably be comfortable with simply defining them and calling later on. But we are also given properties I personally didn't know about until just recently.

We can actually retrieve the function's name as a string from within the code. This way we know which function is being called. And also which function called the function that is being currently executed. These properties are located within the function's prototype object. And some within the function's arguments property. Which, we can modify ourselves. Or simply retrieve existing values from it:

Notes: arguments.callee is forbidden in strict mode. And I am not sure how cross-browser it is.

arguments.callee.length is the number of arguments received by the function. It could be less than the number of arguments specified:

arguments.length is the number of arguments specified in function definition.

caller, callee, and arguments properties may not be accessed on strict mode functions or the arguments objects for calls to them. They appear to be deprecated in ES5 and removed in strict mode. For us it means that this may not work in all browsers. Be careful.

There are two different ways to access the same properties. Through the function's constructor object (Function) and through the arguments object which exists in all functions.

However, Function.caller is implemented in all currently existing browsers. When getting caller from the currently executed function, use the callee (its own) literal name to access it:

function fn() { var caller = fn.caller.name; }

While arguments.caller is deprecated in favor of Function.caller. Sticking to Function.caller is better in this case.

Because these properties are not available in all browsers in all modes (strict or not) the thing about these extras is that we can use them in projects that run locally in our favorite browser (and are not designed for the Internet.) For example, I am using an article publishing program I wrote myself. I always run it in my favorite browser: Google Chrome, where many JavaScript features work that may not in other browsers. Remember that not all JavaScript programs are meant for the public Internet.

And finally, here is source code for obtaining various properties of the function:

function show_props(a,b,c,d,e) { var msg = "function name = " + arguments.callee.name + "\n"; msg += "called from = " + show_props.caller.name + "\n"; msg += "arguments.length = " + arguments.length + " argument(s) were passed.\n" msg += "show_props.length (arity) = " + show_props.length + " argument(s) are defined total.\n"; msg += "arguments = " + arguments + "\n"; for (var i = 0; i < arguments.length; i++) msg += "arguments[" + i + "] = " + arguments[i] + "\n"; msg += "And arguments.callee.toString() is the function's literal body in string format = \n" + arguments.callee.toString() + "\n"; alert(msg); } function parent() { show_props(1,2,3); } parent();

The result is shown below:

function name = show_props called from = parent arguments.length = 3 argument(s) were passed. show_props.length (arity) = 5 argument(s) are defined total. arguments = [object Arguments] arguments[0] = 1 arguments[1] = 2 arguments[2] = 3 And arguments.callee.toString() is the function's literal body in string format = function show_props(a,b,c,d,e) { var msg = "function name = " + arguments.callee.name + "\n"; msg += "called from = " + show_props.caller.name + "\n"; msg += "arguments.length = " + arguments.length + " argument(s) were passed.\n" msg += "show_props.length (arity) = " + show_props.length + " argument(s) are defined total.\n"; msg += "arguments = " + arguments + "\n"; for (var i = 0; i < arguments.length; i++) msg += "arguments[" + i + "] = " + arguments[i] + "\n"; msg += "And arguments.callee.toString() is the function's literal body in string format = \n" + arguments.callee.toString() + "\n"; alert("msg"); }

As you can see we can even output the body of the function that is being executed from within itself, as a string.

Use the Function object (in this case the literal name of the function show_props itself) and the arguments property to gather insight into which function called which, parameter names, number of parameters and function names.

Similarities Between Function Object Constructor and Eval

Function constructors are unique from other object constructors in that they specify the body of the function that will be executed when that function is called, and it is totally custom code.

In computing object are known to have a constructor. The constructor executes code to build the object from the parameters passed to it. The new Function constructor first takes a number of string arguments to name the parameters of the function you're creating.

Then you actually specify the function body (that would otherwise go in between {...here...} in a regular function definition. This is too done by typing in text as a string.

A function body as a string is an interesting concept. Speaking of which. Even though, the security of your website can be compromised when you use eval in your code, we can execute a statement using this method as well:

var x=1; var y=2; var z=0; eval("z=x+y"); alert(z);

Eval actually modified the value of the z variable, though it was untouched outside of eval within the program itself. It is easy to see how it is a security risk. Imagine someone running this on your website from JavaScript console.

When creating functions using the new Function constructor, the body of the function specified as an argument is "evaluated" into a statement in the same way. Turning strings into objects is very common in JavaScript.

Just the weekly tutorials.