Just the weekly tutorials.

Defining Your Own JavaScript Functions and Constructor Objects

What is the difference between arguments and parameters in a JavaScript function? And when should/shouldn't I use them? Should I use them at all, or create my own variables inside the function? Is it right/wrong to use them in any situation in particular?

The answer to all of these questions is a matter of preference and programming style. However, there are things you can and cannot do in JavaScript, and some surprising ways in which you can do things, that are not obvious at first.

This gives us a lot to think about.

A brief distinction between parameters and arguments. The word parameters is used to define the names used inside the function to deal with the arguments that will be passed to it. The arguments themselves are not parameters, rather, they are the actual values/objects passed to the function to be defined by its parameter names. Here is an easy way to remember the difference. Parameters are used when the function is defined. Arguments are used when function is called.

Parameters are defined during the function design stage. What the names are, and how many of them are there is up to the programmer.

// Define a function "my_func" together with its parameters function my_func(a,b,c) { }

Here, a,b and c are function's parameters (parameter names.) And in the following example, this function will be called:

// Call the function "my_func" my_func(1,2,3);

Here, 1,2 and 3 are arguments. They are actual objects of type Number and not mere names. Within the function they will be translated into parameter names so you can start dealing with them, for whatever purpose.

Arguments and parameters are tied into function definition process which is up to the programmer. That is, when you create a function, a decision is made as to how many parameters this function will take.

In JavaScript function parameters are typeless, they only have a name, but the type of the arguments that will be passed to them is arbitrary. Anything value stored in a variable can be passed to any function parameter as an argument:

function my_func(a,b,c) { return a+b+c; } my_func(2,3,5); // returns 10, the sum of 2,3 and 5

The reason the function above works is simply because this is the design the programmer has chosen to use. He (or she) assumed that the a,b and c parameters will always be numeric (integers, or floating point numbers.) The result is the sum of all numbers. Just as expected.

But JavaScript does not care about what type of arguments are passed to any function. This is the task the programmer has to accomplish on their own merit.

Let's see what happens if one of the parameters is a string, not a number as was originally assumed:

function my_func(a,b,c) { return a+b+c; } my_func("2",3,5); // returns "235"

In this case the type of the argument passed actually changed the original design of the function to add numbers together. Instead we got "235". To understand this consider the return value calculated as a+b+c. Why did we get "235"? This happened because JavaScript's internal primitive coercion mechanism stepped in at the sign of string "2", it chose to treat the rest of the values within the equation a+b+c as strings. This, however, has nothing to do with either arguments nor parameters, it's just something JavaScript does additionally for us when it encounters String + Number operations.

Here it is clearly observed that JavaScript function's parameters are typeless. Any kind of a value can be passed to any of the parameter names. What happens inside the function is up to the programmer.

In other words, there is no way a simple JavaScript function would check whether the arguments are of any type in particular. We will see how to handle this problem later in this tutorial.

In addition to this, the parameters are always optional. Knowing that parameters are optional, we can ask the following question:

For instance, when creating your own JavaScript function you may define it as follows:

// always return 1, no matter what arguments were passed function my_func1(a,b,c) { return 1; }

Here is another example where the parameters are actually part of the return value. They are required for the function to return a value.

// a function that will return the sum of 3 numbers (for example) function my_func2(a,b,c) { return a+b+c; }

This makes sense. And what's more, you can even call this function without passing any arguments to it:

var msg = my_func2(); // returns the value of "NaN" ("Not A Number")

This function will return "NaN" (if you display it with an "alert(msg);" box or log it to the browser's console with "console.log(msg);" command.) But again, this has nothing to do with function parameter definitions.

The value of "NaN" which stands for "Not a number" will be returned because of what it says exactly. The parameters were originally "undefined" because none were passed:

var a; console.log(a); // "undefined"

"undefined" is another special value type in JavaScript, it simply means a variable was created but its value was never defined, which is exactly what happened here. The return value of "my_func2" stays true to the rules of JavaScript. The statement a + b + c evaluated to "NaN", which is what one would expect from 3 undefined values:

var a; var b; var c; console.log(a + b + c); // NaN

There is another very interesting thing you will notice when it comes to JavaScript functions. That even if the function definition does not define any parameters, it can still take arguments.

function my_func3() { /* Code here can still work values passed to this function */ }

The function can legally take arguments if they were indeed passed to the function without defined as parameters in function definition. What's more, in JavaScript, they can even be "used" inside a function, even if they weren't stated in the function definition. So what would be their names in this case? Let's take a look at the following code that answers this question:

function my_func3() { var a1 = arguments[0]; var a2 = arguments[1]; var a3 = arguments[2]; var a4 = arguments[n]; // and so forth, for as many as "n" numbers of arguments return a1 + a2 + a3; }

Each JavaScript function has an internal mechanism for tracking arguments. See The Life of JavaScript Functions tutorial for more information. JavaScript function definitions are not strict. This means you can pass any number of arguments to any JavaScript function. When the parameters are forced to be defined during the function definition process by the programmer, it is done only out of convenience so that other programmers can understand where the parameters/arguments came from (such is the case with jQuery for example, when we know that the function $("div") takes a string selector. It's just the way it was defined by whoever created jQuery. $ is just a function name.

Another thing to consider with regard to defining and calling JavaScript functions is that they can have the same name but multiple definitions. In other words, the same function will execute the statements within itself based on how many or what kind/type of parameters were passed to it (a string? an object? an array?) For example, we can write a functions like this:

function func_a(index, obj) { /* do something with index or obj */ }

Clearly in this case the parameters that are defined (by whosoever did define this function) somewhat explain themselves by the merit of their name. For example "index" must be a numeric value. And "obj" must definitely be an object (a plain JavaScript object? a jQuery object? an object of type Date?). Of course some of these details exist in simply assuming that they are true. But let's take a look at the following example where the function actually checks for the type of the object that was passed, assuming nothing, and expecting exactly what it expects to receive as an argument:

function func_b(obj) { if (obj instanceof Object) { // Do something with an object } else { // What was passed was not an object. // This function isn't designed to do anything with non-object variables. // Gracefully degrade (Keep silence about this) or display an error. } }

This puts another twist on function design in JavaScript. The programmer can test if what was passed to a function was indeed an object. But what is the actual advantage of this? There is at least one. In JavaScript not all objects are the same. For example, even though an Array is an object of type Array and a custom object is an object of type Object. Both Array and Object are functions already defined by JavaScript. They are also known as object constructor functions.

The native JavaScript keyword "instanceof" is used to determine whether the variable contains an object of a particular type (Array, String, Number, Date, etc.) If you are planning to define (or design) your own function, here is an example of a few other variable tests to be used inside your function definition:

var obj = {"a": "I am an Object" }; var arr = ["I am an Array"]; var str = "I am a String."; if (obj instanceof Object) { // "true", because obj is a custom JavaScript object // in the form of var obj = {"a": 1 }; } if (arr instanceof Object) { // returns true, and even though this is an object of type Array, // it is still treated as an object of type Object in JavaScript. // Why it is this way -- we may never know the truth behind the // decision made by designers of JavaScript language. // And so, to try and figure out if it is really an array, // we need to test if the object has length method, all arrays do: if (arr.length == undefined) { // This is 99% an array, or an object of // some other non-native type containing "length" method } else { // This is 100% not an object of type Array, // because all arrays have "length" method } } if (str instanceof Object) { // Even though "str" is an object of type String, // and only according to "instanceof" method, // it is not an object of type Object, // like objects of type Array are. }

Why, in the eyes of JavaScript language designers, a plain JavaScript object such as {a:1} is an object of type Object, an Array is an object of type Object, but a "string" is an object of type String is elusive. That's just how the language was designed with regard to JavaScript's "instanceof" function. It is just the way it is. Ideally, we can imagine that an Array would be an object of type Array. There must be a deeper reason for this, but at this point what's important is that we know how "instanceof" identifies different types of objects and which values it considers to be true or false. It's just the way JavaScript chooses to define objects.

Let's take a closer look at JavaScript constructors, because it fits the discussion of JavaScript functions. Constructors are objects. And we know that functions are objects, too. Therefore, some functions are constructors. A constructor function is the kind of a function that fires once, during the construction of the object. When the object is created, it is stored in a variable as a copy of the new object. This new copy is referred to as an instance of an object. It is indeed a new instance of an object, and that is why the keyword is called "new":

var arr = new Array(); var obj = new Object();

What happens here is that we create a new function instance using the "new" operator. We take the already predefined functions "Array" or "Object" (they already exist in JavaScript for us to copy and build our own objects) and instantiate a new function object from them. Each time this happens, the Array or Object (or whatever constructor function you have used) will execute whatever commands that constructor function has already pre-written inside them. Usually for Arrays the constructor function prepares an array object by setting its length to 0, or the actual length of the array being created (if it was passed into the constructor as an argument) and will become stored in a variable ("arr" or "obj" in this example.)

What is the deal with all this JavaScript constructor object / function talk? Are they functions or objects? They are both. And that's legal according to JavaScript specification. In order to understand constructors like Object or Array (and others such as Number, Date, String, etc.) we can create our own constructor. Since we know that all constructor objects are functions, then all we have to do to create a constructor is to create a JavaScript function. The internals of our constructor will set some custom values and add them to the object that will be created from this constructor:

// Create our own constructor object, for whatever purpose // Like others, "Array", "String" were created for their purpose var MyOwnConstructor = function(a) { this.a = a; // within the constructor we refer to object being created using "this" keyword / variable return this; // return the object to the variable it is being assigned to (see below) }; // Build the new object and store it in variable "own" var own = new MyOwnConstructor(7); // Check if "own" is an instance of "MyOwnConstructor" object alert(own instanceof MyOwnConstructor); // It returns "true" alert(own.a); // 7

Constructor objects / functions created as "new String()" and "new Array()" are no longer a mystery. Custom objects you have created can be later reused in the same way String and Array are re-used all the time in scripts written with JavaScript language.

Just the weekly tutorials.