#JavaScript Functions are Objects!
Yes, in JS world a function is considered an object, and to explain the reason why we will have to learn about types. Types in JavaScript are categorized by:
- Primitives (string, number, null, boolean, undefined, symbol): these are immutable data types. They are not objects, don't have methods and they are stored in memory by value.
- Non-Primitives (functions, arrays and objects): these are mutable data types. They are objects and they are stored in memory by reference.
To learn more about primitive vs reference values, you can check out this article and our full course on the "tricky parts of JavaScript".
As you can see, functions are inside the non-primitive category, which means that when you define a function you are creating an object.
Related Premium Courses
#Let's see it in Action!
So let's create a function and treat it like if we just created an object.
Let's assign a variable and log it:
// Function declaration. function showFavoriteIceCream() { const favIceCream = 'chocolate'; console.log(`My favorite ice cream is ${favIceCream}`); } // Let's assign a property. showFavoriteIceCream.flavours = ['chocolate', 'vanilla', 'strawberry']; // Let's log the showFavoriteIceCream function. console.log(showFavoriteIceCream); // Log // { [Function: showFavoriteIceCream] // flavours: [ 'chocolate', 'vanilla', 'strawberry' ] } -> property assigned
Here's what we get:
#Let's assign a function and log it:
// Function declaration. function showFavoriteIceCream() { const favIceCream = 'chocolate'; console.log(`My favorite ice cream is ${favIceCream}`); } // Let's assign a property. showFavoriteIceCream.flavours = ['chocolate', 'vanilla', 'strawberry']; // Let's assign a function. showFavoriteIceCream.showFlavours = function () { return this.flavours; }; // Let's log the showFavoriteIceCream function. console.log(showFavoriteIceCream); // Log // { [Function: showFavoriteIceCream] // flavours: [ 'chocolate', 'vanilla', 'strawberry' ], // showFlavours: [Function] } -> function assigned
Here's what this produces:
As you can see, the showFavoriteIceCream
function besides performing an action, is also behaving as an object, we are able to assign properties and methods to it.
Actually, function are known as first-class objects (or first-class citizens) which means that they can do more than that:
- They can be stored in variables.
// stored in a variable. (Function expression) const showFavIceCreams = function () {}; // stored in an array. const listOfData = ['vanilla', 5, showFavIceCreams]; // stored in object. const thisIsAnObject = { showListOfIceCreams: function () {}, };
Preview
- They can be passed as parameters in another function.
// Function declaration function getFavoriteIceCream() { return 'chocolate'; } // Function declaration with params function logFavoriteIceCream(func) { return func(); } // Passing getFavoriteIceCream as a parameter in logFavoriteIceCream console.log(logFavoriteIceCream(getFavoriteIceCream)); // chocolate
Preview
- They can return from another function.
// Function declaration function getFavoriteIceCream() { const myFavIceCream = 'chocolate'; // Returns another function declaration return function () { return 'My favorite ice cream is ' + myFavIceCream; }; } // storing function returned const functionReturned = getFavoriteIceCream(); // executing function returned console.log(functionReturned()); // My favorite ice cream is chocolate
Preview
Perfect, now we can say that function are objects. Now let's take a closer look at one of the logs:
Why are functions logged as Function (and not as "Object" or something similar)?
Well, it's because functions are not just objects, they are Function objects, meaning that besides being able to assign properties and methods to them, they also have properties and methods already defined by the built-in Function object.
Just like arrays are special kinds of objects - arrays also are regular objects with some pre-defined methods available on them. To be precise, for both the Array
as well as the Function
type objects, the "special" methods are defined on a special prototype.
And what is a built-in object? In JS there are standard built-in objects upon which other objects are based. Said this, the standard built-in Function is the object upon which functions are based.
The built-in Function object has properties like name, length and has methods like call, apply and bind. Let's log some of them to see an existing proof:
// Function declaration. function showFavoriteIceCream(favIceCream) { console.log(`My favorite ice cream is ${favIceCream}`); } // Function Properties console.log('name: ' + showFavoriteIceCream.name); // showFavoriteIceCream console.log('length: ' + showFavoriteIceCream.length); // 1 // Function methods console.log('call: ' + showFavoriteIceCream.call); // function call() console.log('apply: ' + showFavoriteIceCream.apply); // function apply() console.log('bind: ' + showFavoriteIceCream.bind); // function bind()
Preview
name
yields the name you gave the function, length
shows the number of expected parameters. call()
, apply()
and bind()
can help you with calling the function - you can learn more about these methods (mainly about bind()
) in this tutorial.
Knowing this, we can see functions in a totally different perspective, and here is an example of how we can see it behind the scenes:
#Why does all that matter?
If you're new to JavaScript, it can be easy to overlook that functions are objects. And that can make it hard to understand why you can do things like myFunction.bind()
. Or why functions are reference values.
Therefore it is key to understand that functions are not "some special thing" in JavaScript but that they are just objects. Objects with special, built-in methods and properties.
This article was written by Mikjail Salazar, you can visit his LinkedIn profile.