Friday, February 23, 2018

Javascript variables: var vs let vs const

Yesterday, a colleague of mine asked me what the difference between let and var is. This post will clarify some things, hopefully for other people too.

The let keyword is a new keyword for declaring variables and it works differently than var. To help demonstrate the difference, let’s quickly review two characteristics of var and JavaScript: hoisting and functional scope.

Var in JavaScript works a bit differently than similar keywords in other languages. For example, let’s consider this JavaScript function:
If the ‘hour’ parameter is less than 18 it appears that we are declaring variable called ‘greeting’ (line of code: 3) and if the ‘hour’ parameter is greater or equal to 18, it looks like we are declaring a different variable called ‘greeting’ (line of code: 5). This may be an issue in other languages, but in JavaScript, these two ‘greeting’ variables are actually the same. Anytime a var is used in JavaScript, something called hoisting happens. Behind the scenes, the JavaScript code is rewritten so that all variable declarations using the var keyword in a function are hoisted to the top of that function. This means that in reality, the code we wrote looks like this when it executes:
One declaration of ‘greeting’ is hoisted to the top of the function and any other declarations of ‘greeting’ are ignored. Because the var keywords are ignored after hoisting happens, lines of code four and six are normal assignments. We can prove this behavior, with doing something really unusual. Let’s move the declaration of ‘greeting’ down to the bottom of the function. I don’t recommend doing this because it’s really confusing, but because of hoisting this code will still work as it’s expected, even it looks like that the declaration of ‘greeting’ is blocked by the return statement and will never be reached.

The next important thing to understand about var is scope. The var keyword uses a functional scope. We already saw that the uses of the var keyword inside a function get hoisted to the top of that function. Uses of var outside of a function are considered part of the global scope and get hoisted to the “top” of the global scope. This global scope is shared even across different scripts and redeclaring the global variable with var has no effect for the same reason that redeclaring a function’s variable with var has no effect. The declarations are essentially consolidated when they are hoisted. For example, if we have script1.js and script2.js and both declare a variable called ‘person’ using the var keyword, JavaScript treats this as a single variable in the global scope. The value of person at any given time depends on the order in which these scripts are referenced. So, this isn’t anything new, it’s how var is working in JavaScript all long.

Now, that we reviewed var keyword, let’s talk about the new ES6 keyword: let. As we said, var hoists and uses function scope. The new ES6 keyword let is different than var because variables declared with let are not hoisted and they use block scope. Well, let’s go back to the original example, but change each var keyword to let. Now TypeScript gives us an error “at line 7, Cannot find name ‘greeting'”:


Firstly, the let keyword in ES6 has block-scope. Blocks can generally be thought of as closest containing a set of curly braces. This will be familiar to those, who also know languages like C, CSharp or Java. With let, the first ‘greeting’ (line of code: 3) is a variable that has only scope to the if-statement curly braces and the second ‘greeting’ (line of code: 5) is variable that has only scope to the else-statement curly braces. Because it has this branch scope, the final declaration of ‘greeting’ in the return statement doesn’t reference anything at all, which is why TypeScript gives us an error. So, what the var keyword gives us function scope, the let keyword gives us block scope. What happens if we fix this by adding a new line to declare the variable at the top of the function?

Now, this is even worse, because we’ve got three versions of ‘greeting’, the one we just made in the block scope of the function and a separate one in each of the if-branches. As written, this function will always return undefined, because the values are only set on the variable scope to the branches, not the one declared at the top of the function. To get the story correctly, we need to remove the let keyword in each branch:
Now, there is one ‘greeting’ variable that exists throughout the function and it will work as intended. The second major difference from var is that the let keyword doesn’t hoist. Try to declare the let keyword after the return statement and you will get an error: “block-scoped variable ‘greeting’ used before its declaration”. The reason we are getting this error is that variables declared with let are not hoisted. Because of hosting, it’s ok to redeclare a variable with the var keyword inside a scope. The var keywords are hoisted to the top of function scope. However, with let redeclaring a variable on the same scope becomes a duplicate identifier error. This could be useful to identify possible bugs in your program.

Using let in a for-loop

A special case that I want to highlight when let keyword bends the rules of block scoping and that’s when let is used to declare the iterator variable in a for-loop. Let’s consider the following function called printNumbers:

It's designed to naively log out numbers from one to whatever number is passed in as the max parameter. What happens if we add a line of code that consoles ‘i’ outside the loop?
If we didn’t understand hoisting and functional scope in JavaScript, you might expect this would be an error. However, now we know, when var is used, the declaration of ‘i’ is hoisted to the top of the function. So, ‘i’ remains in scope throughout the entire function. If we call print numbers with a max of 10, the extra console.log we added (line code: 5) will log 11. That’s the first number that met the for-loop exit condition. For-loop iterators declared with var, are not reset when the loop exits.

If we were duplicated the loop and reuse ‘i’ iterator, our code now uses the same ‘i’ variable in both loops:
The variable ‘i’ is reset at the top of each loop so the iteration will work as expected. But if we were using ‘i’ for something else inside this function, its previous value would be lost. The lines with var are treated as an assignment to the same function’s scoped ‘i’ variable in both loops, they don’t create their own variable.

Let’s switch these var keywords to let. As we said before, ES6 slightly bends the rules of block scoping, when let is used to initialize a for-loop:
Even if it’s technically outside the curly braces, the iterator of the for-loop declared with let is scoped to be inside the braces. With this code, a separate ‘i’ variable is now scoped within each for-loop only. No ‘i’ variable exists in the middle anymore. That’s why TypeScript shows an error for our extra console.log(i) statement (line of code: 5):

Scope per iteration behavior of let

ES6 has another very interesting behavior when let is used to initialize the for-loop, beyond just keeping the iterator scope to the loop’s curly braces. Using let creates a separate copy of the variable for each iteration through the for-loop. To demonstrate why this is useful, let’s take a look at this example:
First, we declare the for-loop using the var keyword and later, the handler function for the button onclick event is created. If we run the example, every click on the button is going to alert the same message: “This is button 4”. The base of what we know about the var keyword, it’s not surprising that the ‘i’ declared in the click handler is the same ‘i’ declared in the for-loop. However, what it’s often surprising is that each iteration through the for-loop refers to the same ‘i’ variable. A copy of its value is never made and so each click handler alerts the same message, for the first value of ‘i’ that met the for-loop exit condition and that value is preserved in the closed scope shared by each click handler. So, how we fix this?  To get this to work as intended in ES5 JavaScript, we have to manually create a new scope that will close over the value of ‘i’ in each iteration. That way, each handler can display the appropriate message. A common way is to wrap the code that creates the click handler in an Immediately-Invoked Function Expression or IIFE:
So, now each run through the loop will have a separate function that retains access to a separate closed over scope. That includes a different value for ‘buttonNumber’ variable. If we run the example again, we can see that the code works as expected. However, that seems like a lot of work. In ES6, we can just use the let keyword to declare our variable in the for-loop and this behavior happens automatically for us. When using let within a for-loop, each iteration gets a separate copy of the iterator variable and its own scope, which eliminates the need of IIFE:


Introduction to const

The const keyword in ES6 is very similar to let. Variables declared with const are also blocked scoped and aren’t hoisted. The main difference is that the value of a const must be set when it’s declared and cannot be changed later in the scope. In ES6, you have to provide the value for a const, when it’s declared:

const myvar;


Const in ES6 behaves a bit differently than in some other languages though. For example, an ES6 const can’t be instantiated to return value of a function or an expression. Also, it doesn’t have to be a true constant, like a string literal or a number. This means that code like this:

const startTime = Date.now();
const answer = confirm('Are you sure?');

works perfectly fine. Const effectively prevents reassigning a new value, even when it’s used to declare an object. Let’s create an object literal:

const simpleLiteral = {
  myProperty: 1
};

If we try to set the ‘simpleLiteral’ to a new value, TypeScipt shows us an error:

const simpleLiteral = {
  myProperty: 1
};

simpleLiteral = {
  myProperty: 1
}


However, if we try to set the value of a property of ‘simpleLiteral’, this works fine:

const simpleLiteral = {
  myProperty: 1
};

simpleLiteral.myProperty = 2;

So, it’s important to remember that the value of an ES6 const itself must remain constant, but the value of any of its properties may be changed. Does that mean that there is no way to have properties of an object being constant via the const keyword? Well, it’s possible to be achieved using TypeScript namespaces. A namespace is a new keyword that was introduced in TypeScript version 1.5. It replaces the uses of the module keyword. Namespaces are TypeScript only concept and not part of the ES6 standard. Let’s do a quick test of how properties declared with const working in TypeScript namespace:

namespace AtomicNumbers {
  export const H = 1;
  export const He = 2;
};

The export keyword means that these properties are available outside of the namespace keyword. If we try to redeclare some of the properties, we will get an error that we cannot redeclare block-scoped variable:

namespace AtomicNumbers {
  export const H = 1;
  export const He = 2;
};

AtomicNumbers.H = 3;

We get this error, even if we try to modify the namespace from outside.

When to use let and const?

So, when should we actually use let and const with ES6 and TypeScript 1.8? I think that using the new keywords where appropriate can help to clarify the intended purpose and scope of the variables. As a bonus, it’s also nice to eliminate the hand-coding IIFEs in for-loops. If we are looking for a good recommendation, I think a fair one is that first, we should try to use var, when you intend for variables to be resistant to the declaration. Mostly this will be for intentionally global variables that are used across files. That scenario should be pretty rare. The second case, when you may still wish to use var, is inside a function if the block scoping behavior of let and const creates an awkward situation. For an example, try-catch block. Pretty much, we should use let and const at all other times. The tighter scope of let and const declared variables will hopefully lead to more correct programs that are easier to understand. In addition, we should try to use const over let as much as possible. You will be surprised how often variables don’t need to be updated after being initialized, particularly object literals (don’t forget, that we can update the properties of a const). A cool thing about using TypeScript is that can tell you instantly of a variable you declare with const if it’s ever used in left-hand side of an expression. For these variables, you just need to use let instead.

Thursday, January 3, 2013

JavaScript Interfaces


The interface is one of the most useful tools in the object-oriented JavaScript programmer’s toolbox. The first principle of reusable object-oriented design mentioned in the Gang of Four’s Design Patterns says “Program to an interface, not an implementation,” telling you how fundamental this concept is.

The problem is that JavaScript has no built-in way of creating or implementing interfaces. It also lacks built-in methods for determining whether an object implements the same set of methods as another object, making it difficult to use objects interchangeably. Luckily, JavaScript is extremely flexible, making it easy to add these features.

However, using interfaces is not entirely without drawbacks. JavaScript is an extremely expressive language, in large part because it is loosely typed. Using interfaces is a way of partially enforcing strict typing. This reduces the flexibility of the language. Using any interface implementation in JavaScript will create a small performance hit, due in part to the overhead of having another method invocation. The biggest drawback is that there is no way to force other programmers to respect the interfaces you have created. In other languages, the concept of the interface is built-in, and if someone is creating a class that implements an interface, the compiler will ensure that the class really does implement that interface. In JavaScript, you must manually ensure that a given class implements an interface. You can mitigate this problem by using coding conventions and helper classes, but it will never entirely go away.

Pro Javascript Design Patterns book explores three ways of emulating interfaces in JavaScript:
  • comments, 
  • attribute checking, and 
  • duck typing. 
No single technique is perfect, but a combination of all three will come close.

Describing Interfaces with Comments

The easiest and least effective way of emulating an interface is with comments. Mimicking the style of other object-oriented languages, the interface and implements keywords are used but are commented out so they do not cause syntax errors. Here is an example of how these keywords can be added to code to document the available methods:

This doesn't emulate the interface functionality very well. There is no checking to ensure that CompositeForm actually does implement the correct set of methods. No errors are thrown to inform the programmer that there is a problem. It is really more documentation than anything else. All compliance is completely voluntary. 

That being said, there are some benefits to this approach. It’s easy to implement, requiring no extra classes or functions. It promotes reusability because classes now have documented interfaces and can be swapped out with other classes implementing the same ones. It doesn't affect file size or execution speed; the comments used in this approach can be trivially stripped out when the code is deployed, eliminating any increase in file size caused by using interfaces. However, it doesn't help in testing and debugging since no error messages are given.

Emulating Interfaces with Attribute Checking

The second technique is a little stricter. All classes explicitly declare which interfaces they implement, and these declarations can be checked by objects wanting to interact with these classes. The interfaces themselves are still just comments, but you can now check an attribute to see what interfaces a class says it implements:


In this example, CompositeForm declares that it implements two interfaces, Composite and FormItem. It does this by adding their names to an array, labeled as implementsInterfaces. The class explicitly declares which interfaces it supports. Any function that requires an argument to be of a certain type can then check this property and throw an error if the needed interface is not declared.

There are several benefits to this approach. You are documenting what interfaces a class implements. You will see errors if a class does not declare that it supports a required interface. You can enforce that other programmers declare these interfaces through the use of these errors. The main drawback to this approach is that you are not ensuring that the class really does implement this interface. You only know if it says it implements it. It is very easy to create a class that declares it implements an interface and then forget to add a required method. All checks will pass, but the method will not be there, potentially causing problems in your code. It is also added work to explicitly declare the interfaces a class supports.

Emulating Interfaces with Duck Typing

In the end, it doesn't matter whether a class declares the interfaces it supports, as long as the required methods are in place. That is where duck typing comes in. Duck typing was named after the saying, “If it walks like a duck and quacks like a duck, it's a duck.” It is a technique to determine whether an object is an instance of a class based solely on what methods it implements, but it also works great for checking whether a class implements an interface. The idea behind this approach is simple: if an object contains methods that are named the same as the methods defined in your interface, it implements that interface. Using a helper function, you can ensure that the required methods are there:

This differs from the other two approaches in that it uses no comments. All aspects of this are enforceable. The ensureImplements function takes at least two arguments. The first argument is the object you want to check. The other arguments are the interfaces that the first object will be compared against. The function checks that the object given as the first argument implements the methods declared in those interfaces. If any method is missing, an error will be thrown with a useful message, including both the name of the missing method and the name of the interface that is incorrectly implemented. This check can be added anywhere in your code that needs to ensure an interface. In this example, you only want the addForm function to add the form if it supports the needed methods.

While probably being the most useful of the three methods, it still has some drawbacks. A class never declares which interfaces it implements, reducing the reusability of the code and not self-documenting like the other approaches. It requires a helper class, Interface, and a helper function, ensureImplements. It does not check the names or numbers of arguments used in the methods or their types, only that the method has the correct name.

Pro Javascript Design Patterns book is using a combination of the first and third approaches. Authors use comments to declare what interfaces a class supports, thus improving reusability and improving documentation. Also, authors use the Interface helper class and the class method Interface.ensureImplements to perform explicit checking of methods. They return useful error messages when an object does not pass the check.

Here is an example of the Interface class and comment combination:

Interface.ensureImplements provides a strict check. If a problem is found, an error will be thrown, which can either be caught and handled or allowed to halt execution. Either way, the programmer will know immediately that there is a problem and where to go to fix it.

And here is the  Interface class that we use it the above example (Interface.js):

As you can see, it is very strict about the arguments given to each method and will throw an error if any check doesn't pass. This is done intentionally, so that if you receive no errors, you can be certain the interface is correctly declared and implemented.

Another example using Interface class in Pro Javascript Design Patterns book is as follows:

Imagine that you have created a class to take some automated test results and format them for viewing on a web page. This class's constructor takes an instance of the TestResult class as an argument. It then formats the data encapsulated in the TestResult object and outputs it on request. Here is what the ResultFormatter class looks like initially:



This class performs a check in the constructor to ensure that the argument is really an instance of TestResult; if it isn't, an error is thrown. This allows you to code the renderResults method knowing confidently that the getDate and getResults methods will be available to you. Or does it? In the constructor, you are only checking that the resultsObject is an instance of TestResult. That does not actually ensure that the methods you need are implemented. TestResult could be changed so that it no longer has a getDate method. The check in the constructor would pass, but the renderResults method would fail.


The check in the constructor is also unnecessarily limiting. It prevents instances of other classes from being used as arguments, even if they would work perfectly fine. Say, for example, you have a class named WeatherData. It has a getDate and a getResults method and could be used in the ResultFormatter class without a problem. But using explicit type checking (with the instanceOf operator) would prevent any instances of WeatherData from being used.


The solution is to remove the instanceOf check and replace it with an interface. The first step is to create the interface itself:


This line of code creates a new instance of the Interface object. The first argument is the name of the interface, and the second is an array of strings, where each string is the name of a required method. Now that you have the interface, you can replace the instanceOf check with an interface check:

The renderResults method remains unchanged. The constructor, on the other hand, has been modified to use ensureImplements instead of instanceOf. You could now use an instance of WeatherData in this constructor, or any other class that implements the needed methods. By changing a few lines of code within the ResultFormatter class, you have made the check more accurate (by ensuring the required methods have been implemented) and more permissive (by allowing any object to be used that matches the interface).

Wednesday, December 19, 2012

Back to basics - Function Declarations

In this simple post I am going to show you what's the preferred way of declaring JavaScript functions. We are going to create anonymous functions and assigning them to a variable.

This is an anti pattern in JavaScript (don't do this):
The preferred way of declaring a JavaScript function is creating anonymous function and assigning it to a variable:
Benefits of this type of function declaration are:

1. Makes it easier to understand "functions as an object".
2. It enforces good semicolon habits.
3. Doesn't have much of the baggage traditionally associated with functions and scope.

Also we can declare named function expression as follows:
Benefits of this type of function declaration are:

1. Provides the debugger with an explicit function name: helps stack inspection.
2. Allows recursive functions: someFunction can call itself.

But with this type of function declaration there are historic quirks with IE.

Tuesday, September 11, 2012

Recursive setTimeout pattern

The Recursive setTimeout pattern is most commonly used when we want periodically running a piece of functionality, related to duration (most commonly used to query a data source).

This may sounds like what setInterval does, but there is a problem with using setInterval. Because JavaScript is asynchronous, setInterval method actually does not wait for the previous function to finish it's execution before begins the next time period. What if the function was waiting for an AJAX response? Function execution can get out of order.

So, the idea is to use setTimeout. setTimeout can ensure order of execution:

Monday, September 10, 2012

Asynchronous execution pattern

Before we go thought this pattern, lets cover some basic notes about JavaScript timers:

1. There two kinds of timers in JavaScript:
  • setTimeout
  • setInterval
2. Both take two arguments, a function to invoke and a delay period
3. setTimeout will execute the function once
4. setInterval will execute continuously with the specified delay between each execution
5. Delays < 4ms will be bumped to 4ms
6. Important: Timers wont start until the outer most function is finished

Browsers are typically single threaded, they either update the UI or executing JavaScript. Long running JavaScript blocks the UI and browser is unresponsive.

Splitting long-running code over setTimeout blocks releases the thread:

  • While processing a loop limit the scope to a small time window
  • Ensure that there is enough of a gap between timeouts restarting

So let's see a basic example:



So, this is very trivial example, but it's very common scenario in web applications when we gather data through ajax. The problem which can arise is that we don't know how long the process will take, or on low power devices such as mobiles or tablets processing this array could take a lot longer than we would like and UI can stop responding.

One way we can get around this is to create a function which will allow us to defer the execution on multiple periods of time:

Observable properties pattern

If you’re familiar with C#, think about the INotifyPropertyChanging and INotifyPropertyChanged interface to implement observable properties.

Here are some points before we implement observable properties in JavaScript:

- Properties  implemented as methods
- Check the incoming value and decide if you want to update
- Return private variable
- Store event handlers in an array
- Utilise return values to abort the updating process

Here is the implementation:


Note: With ECMAScript5 properties can have methods body (similar to how .NET properties look) and it's very powerful, but be careful because this option is available in current generation browsers.

Here is an example:

Chaining pattern

Method chaining is a common technique for invoking multiple method calls in object-oriented programming languages. Each method returns an object (possibly the current object itself), allowing the calls to be chained together in a single statement (Wikipedia definition). This technique was made popular in several libraries, like jQuery.

Let's see JQuery example of method chaining:

Here is how we can implement method chaining in JavaScript (Calculator example):