Function Expressions vs Function Declarations In JavaScript

Hello everyone! Today I’m going to talk to you about function expressions, function declarations what’s best to use, when to use and more importantly how to avoid unexpected behavior when using them. A lot of newcomers to JavaScript find this confusing but I’m here to convince you that it’s pretty simple:

This is a function declaration:

function foo(){
	console.log("I am foo");
}

This on the other hand is a function expression:

var foo = function(){
	console.log("I am foo");
}

In either case you execute foo in the same way:

foo();

The same thing applies if foo takes one ore more parameters:

function foo(param1, param2){
	….
}

var foo = function(param1, param2){
	….
}

Then you can call it like this:

foo("bar", 3.14);

So I can use whatever I like best and there is no real difference between the two besides the syntax used during the function definition?
The answer is No

Consider the two following examples:

Example 1:

foo();

function foo(){
	console.log("I am foo");
}

Output: “I am foo”

Example 2:

foo();

var foo = function(){
	console.log("I am foo");
}

Output: Uncaught TypeError: foo is not a function

Why is this happening? The reason has to do with hoisting. When you use a function declaration you can imagine that during the first pass of the compiler the function and variable declarations will be moved to the top of the enclosing function (that’s not exactly what really happens but it’s very convenient to imagine it like that). When you use a function expression, only the variable declaration will be “moved” to the top of the enclosing function. You can visualize the result of hoisting in both examples like this:

Example 1 (after hoisting):

function foo(){
	console.log("I am foo");
}

foo();

Example 2 (after hoisting):

var foo;

foo();

foo = function (){
	console.log("I am foo);
}

As you can see in the second example when the engine executes the statement ‘foo();’ it does not possess sufficient knowledge about foo. At that time it only knows that foo is a variable, the actual assignment takes place later in the code.

This is actually the most important thing between function declarations and function expressions

Hoisting

Ok so this is going to be a short one. I recently stumbled upon a question in StackOverflow (actually include a link here) that was asking something like this:

Why is this code valid?

//Start of this file
myFavoriteMovie = "Star Wars"
console.log(myFavoriteMovie);   //Actually prints 'Star Wars' even though `myFavoriteMovie` is undeclared
.
.
.
// A few more lines of irrelevant code
.
.
.
var myFavoriteMovie = "Inception";   //myFavoiteMovie declared
console.log(myFavoriteMovie);

So what do you think would be the output of this script?
Most people would say that an error will be shown claiming that `myFavoriteMovie` is undefined or that `undefined` will be printed in the console. The strange thing is, that the same people that find this code wrong, will find the following code fine:

var game = new VideoGame("Mass Effect", "Bioware", "Action RPG");
console.log(game);

function VideoGame(title, developer, genre){
	this.title = title;
    this.developer = developer;
    this.genre = genre;
}

Those two examples are essentially the same thing. In the first example, `myFavoriteMovie` is used before declaration. In the second example, the same thing happens with the VideoGame function. It’s used before declaration but few people notice the similarity. I too, could not see it and I was surprised when I found out. I think the source of confusion for most of us is that using a variable before declaration is counterintuitive, it’s something that we normally do not do and if we do it’s probably by mistake. However, defining a function or a class at the end of a file and using it before declaring it is rather common because it helps some developers (including me) with code organization. But using a variable before declaring seems off to the most of us. Perhaps that’s because most of us started coding in a more strict language than JavaScript, C for example where it is unthinkable to use a variable before declaring it.

Anyway, there is a name for this and that’s Hoisting. It’s something that happens every time you run your JavaScript script (or just JavaScript 😛 ). Hoisting is the process of moving all variable, function and class declarations found in the file, at the start of that file. So right before execution the code of the first example gets transformed and ends up looking like this :

var myFavoriteMovie = "Inception";
myFavoriteMovie = "Star Wars";
Console.log(myFavoriteMovie);
.
.
.
// A few more lines of irrelevant code
.
.
.
myFavoriteMovie = "Inception";
console.log(myFavoriteMovie);

That is why you can use variables, functions, classes and objects before you actually declare them.

Hope you find this explanation of JavaScript Hoisting helpful. Check more awesome JavaScript stuff here

Custom HTML Elements

Hi, everyone! We’re back to Aurelia and this time I’m going to show you how to build your own custom element just with HTML, without a view-model. Yes, that’s possible!

There are many advantages to an HTML-only element, like, first and foremost, not having to use a view-model at all! This is particularly useful when your custom element does not implement complex business logic but you just need a quick component for your applications.

Now, HTML-only custom elements bring us some good and some bad news.

The good news is that you can still add bindable custom attributes to your elements by adding them to the bindable attribute of the template element in a comma separated fashion:

//my-element.html
<template bindable="attributeOne, attributeTwo, attributeThree ">
….
</template>

 

You can then use it like that: 

<require from="./my-element.html"></require> 
<my-element attribute-one="someVar1" attribute-two="someVar2"></my-element> 

 
Yes, Aurelia does the conversion from camelCase to dash-case on its own all the time. That comes in handy.  
One thing you might have noticed in the example above is that, in order to use an HTML-only element, you also need to include the “.html” extension in your path. That happens mainly due to the absence of a view model. 
 
The bad news is that HTML-only custom elements do not support two-way binding by default. That means that, if you want two-way binding functionality, you need to explicitly state it. I will demonstrate this with a simple example as it can be very confusing to newcomers: 

The HTML-only element:

And how we can use it: