Javascript is an ever-growing language, especially now that releases for ECMAScript specifications now operate on a yearly release schedule. As such the importance of needing to know Javascript beyond just jQuery becomes even more important as the language grows in scope and quite quickly.
This isn’t a definitive guide that claims to be the holy grail of Javascript developer knowledge. There are definitely things I have missed, things I might be wrong about and things you might disagree with as being something every Javascript developer should know.
How to FizzBuzz
Often regarded as a nice coding exercise to weed out the inexperienced developer earlier on in the interviewing process, you would be surprised how many Javascript developers do not know how to write a basic FizzBuzz test.
The FizzBuzz test serves no practical real world purpose whatsoever. It is purely a simple exercise to test would-be candidates on their coding abilities.
Keep in mind most places you will interview at for a front-end/Javascript development position there is a high chance you will be asked a FizzBuzz question: are you ready?
This is the classic FizzBuzz:
Keep in mind that you might be asked to solve different variants of FizzBuzz. I went to an interview once where I was asked to solve the basic variant and then two other variants.
This particular example prints out “Fizz” at multiples of 3. Prints out “Buzz” at multiples of 5 and prints out “FizzBuzz” at multiples of 3 and 5.
Note: A slight change was made to this implementation from what it was earlier. Conditional if statements are used and the number is printed out if it isn’t one of the conditional multiples. The existing solution did work, but it did not print out non conditional numeric values or use conditional ifs.
01 |
for ( var i = 1; i <= 100; i++) {
|
02 |
|
03 |
if (i % 15 === 0) {
|
04 |
console.log( 'FizzBuzz' );
|
05 |
} else if (i % 3 === 0) {
|
06 |
console.log( 'Fizz' );
|
07 |
} else if (i % 5 === 0) {
|
08 |
console.log( 'Buzz' );
|
09 |
} else {
|
10 |
console.log(i);
|
11 |
}
|
12 |
} |
The difference between == and ===
Once again, two comparison operators you are probably familiar with. However, do you know what the difference is between double and triple equal comparison operators? Your Javascript linter tells you to use triple equals, but do you know why?
== Double equals (aka loose equality) will not compare the type, however it will typecast values being compared within the statement. This is called type coercion and it is regarded as an evil operation.
1 |
console.log(24 == '24' ); // true
|
As you can see, our value of 24 within single quotes which is a string is being typecast to a number instead. While there might be situations where this is the desired behaviour, allowing the comparison operator to change your type is probably not what you want to do.
Using the double equals is not recommend and most sane Javascript linters will throw an error telling you to use the strict equality comparison operators instead by default. If you want to coerce values, do so outside of the condition not within it.
=== Triple equals (aka strict equality) will compare the type, but will not typecast the values meaning they are compared as is without being transformed. Because there is no type coercion, the triple equals is faster and the recommended approach for comparing all kinds of values. This means both types need to be the same for the condition to equal true.
The same example as above, but triple equals:
1 |
console.log(24 === '24' ); // false
|
The reason false is being returned is because we are comparing a number to a string. Obviously they are two different distinct types, so it will return false as the result because they are compared as is.
I highly suggest you read up more on equality comparisons on the Mozilla Developer site here. It has some great explanations (better than mine) and also some examples.
How to query the DOM without a 3rd party library
You probably know how to query the DOM using jQuery quite well, but can you do it using native methods in Javascript without resorting to the use of a third party library?
I am not just talking about being able to query the page for an element with an ID or elements with a particular class, I mean jQuery like expressions for finding elements in the DOM.
There are quite a few native methods we can use that are just as powerful as jQuery for finding one or more elements within a page. We can use selectors like first-child, last-child and more. You would be surprised just how good native DOM querying methods are nowadays.
Study these native methods and use them in place of something like jQuery:
Where necessary I have linked off to Mozilla’s developer documentation for further reading. Anywhere you see a link, if you’re not too familiar with something, I highly recommend you click it.
- document.getElementById – The classic query for finding elements via their ID.
- document.getElementsByClassName – Finding elements in the DOM via their className value.
- document.querySelector – This is a great method. It has all of the power of a jQuery $() however, it is native. This will only return the first element that it finds though.
- document.querySelectorAll – Pretty much the same as the above method except that it returns multiple elements that it finds and not just the first one.
- document.getElementsByTagName – This allows you to query for elements of a particular tag name. Want to find all DIV elements in the page or span tags? This is the method you want.
Worth mentioning is the querySelector
and querySelectorAll
methods can also be used on an Element
meaning you can query the contents of an element using these methods.
Read more about Element.querySelector and Element.querySelectorAll for examples of their use.
Hoisting
Javascript is an interesting language purely from the way declarations are hoisted to the top of a scope. This means you can actually reference a variable before you’ve defined it within the current scope (so for example a function is considered its own scope).
As a rule of thumb: ALWAYS define your variables at the top of your desired scope. If you are using ‘use strict’;
at the top of your script files (or within your functions), an error will be thrown if you try using a variable before it has been defined. This statement becomes even more important if you’re using the new block-level scope variables feature in ES6 let
.
Most Javascript linters like Jshint will complain if you haven’t defined ‘use strict’ anyway, so provided you’re applying best practices it should be impossible to use variables before they are defined.
As always the Mozilla Developer documentation has a great article on grammar and types in Javascript and a section which touches upon hoisting here.
How to use browser developer tools
More specifically how to debug Javascript, but also being aware of the other tools you get in the developer tools. How to set a breakpoint and step in and through a certain subset of code within your application.
These tools are important because they allow you to trace the steps in a potentially complicated application and find what is causing an issue or particular bottleneck. Knowing how to set a breakpoint, how to really drill down into your code on a molecular level and see things as they happen.
Understanding the tools that come bundled within Chrome, Firefox and later versions of Internet Explorer is an essential skill to have, especially if you find yourself working with Javascript a lot. Also being aware of the various developer tool addons like Angular’s Batarang extension for Google Chrome that allows you to debug AngularJS applications.
Never blindly optimise your code without first using the appropriate tools to find actual problems and go from there. Solving problems before you have them is called premature optimisation and can be a waste of time.
Console commands
Leading off from the last point, in addition to knowing how to use profiling and debugging tools in Chrome, Firefox or Internet Explorer Developer tools, you should also be aware of the various console commands you can use.
You probably already know of console.log
and possibly console.error
but there are actually a few useful console commands you can use.
Please keep in mind that some of these commands might not work in various browsers. I have been mindful to only list commands that should be well supported in modern browsers, but always try before you go littering your code with potentially unsupported commands.
-
console.log
– For basic logging, I use this for general messages about actions taking place within my code. Format identifiers are also supported within this console call. -
console.error
– For logging errors in your code. I use console.error within error callbacks on AJAX requests and anywhere else an error might be thrown. While similar to console.log, this method also includes a stack trace where the error was thrown. -
console.dir(object)
– This handy method can print out a Javascript representation of an Object in your console window. Can be quite handy. -
console.group(title)
– This allows you to create a group of console logging commands with an optional title. Meaning you can group similar logging messages together say for example when a section of code is responsible for one task. -
console.groupCollapsed
– Exactly the same as the above method, except for the fact the initial group is collapsed and not opened. -
console.groupEnd
– This allows you to end the group defined above. -
console.time(label)
– Allows you to benchmark how long a particular block of Javascript code takes in milliseconds. Especially helpful for benchmarking possible bottleneck methods. -
console.timeEnd(label)
– Similar to the groupEnd method, this allows you to stop the timer logging function and the elapsed time will be printed out in the console. -
copy(string)
– There is a method in the Chrome and Firefox console that allows you to copy the contents of a string to the clipboard. Open up Developer Tools and try it, it can come in handy at times.
Know what this
is
Arguably the largest source for developer confusion is this
. More specifically, what the value of this
actually is. It depends on the context that it is being used within.
In most cases, the value of this
actually refers to that of the global object aka window
. But there are times when the semantics of this
can get very tricky.
Rather than trying to explain all of the different scenarios and the value of this
, lets run through some examples instead.
Call a function
When calling a function the value of this
remains the global window
object. The value of this
is window
because declaring a function like below is effectively declaring a method of the window
object.
1 |
function contextOfThis() {
|
2 |
console.log(this === window); // true
|
3 |
} |
4 |
5 |
contextOfThis(); |
Call an object method
When calling a method that is on an object constructor, the value of this
refers to the instance of the object itself. Pretty similarly to how ES6 classes work and classes in most languages.
01 |
function contextOfThis() {
|
02 |
this.theContext = this;
|
03 |
} |
04 |
05 |
contextOfThis.prototype.getContext = function (obj) {
|
06 |
console.log(this === window); // false
|
07 |
console.log(this === obj); // true
|
08 |
} |
09 |
10 |
var ref = new contextOfThis();
|
11 |
ref.getContext(ref); |
Call or Apply
Call and apply are methods that allow us to call methods as if they were on another object. The first argument of both call
and apply
are the context. The value of this
becomes whatever object you supply as the first argument. You can also supply null
as the first value.
1 |
var newContext = {};
|
2 |
3 |
function myConstruct(name) {
|
4 |
console.log( 'My object name is: ' , name);
|
5 |
console.log(this === window); // false;
|
6 |
console.log(this === newContext); // true
|
7 |
} |
8 |
9 |
myConstruct.call(newContext, 'newContext' );
|
We will touch upon the difference between these two methods shortly. They are both effectively the same, except call
expects comma separated arguments and apply
accepts an array.
Using bind
The bind method when called on a function changes the value of this to whatever the supplied object is. Using bind
allows us to keep the context of this
within another function. You might have used various solutions, most commonly storing a reference to this
inside of a variable called “that”.
01 |
function API(url) {
|
02 |
this.url = url;
|
03 |
} |
04 |
05 |
API.prototype.fetch = function () {
|
06 |
console.log(this === window); // false
|
07 |
08 |
setTimeout( function () {
|
09 |
console.log( 'Timeout without using bind: ' , this === window); // true
|
10 |
}, 500);
|
11 |
12 |
setTimeout( function () {
|
13 |
console.log( 'Timeout using bind: ' , this === window); // false
|
14 |
}.bind(this), 1000);
|
15 |
}; |
16 |
17 |
var request = new API( 'http://www.google.com' );
|
18 |
request.fetch(); |
Taking the second example in the fetch method, lets quickly show what developers used to do (and sadly some still do this).
01 |
function API(url) {
|
02 |
this.url = url;
|
03 |
} |
04 |
05 |
API.prototype.fetch = function () {
|
06 |
var that = this;
|
07 |
08 |
setTimeout( function () {
|
09 |
console.log( 'Timeout using pointer to "this": ' , that === window); // false
|
10 |
}, 500);
|
11 |
}; |
12 |
13 |
var request = new API( 'http://www.google.com' );
|
14 |
request.fetch(); |
While there was nothing wrong with the above approach (hey, it works), it isn’t exactly the cleanest solution in the face of using bind
.
Some further reading on this
can be found here on Quirksmode. It runs through some examples and explains things further than I have. The Mozilla Developer documentation also has some great explanations on “this” complete with exampleshere.
‘use strict’;
As briefly touched upon earlier, use strict (which was added in ECMAScript 5) allows you to enable a more strict variant of Javascript. Every bit of Javascript you write should use this and for good reason.
By default Javascript is a little forgiving in what it will let you do. It will fail silently when you reference a variable before it is declared and try do various other things you didn’t realise were bad, but Javascript wasn’t telling you.
There is a whole article on the subject here over at Mozilla Developer and I implore that you read it because it goes into more detail than I have here.
How to write various types of loops
You would be surprised how many developers I have come across who don’t know how to write a proper for..loop nor aware of the other types of loops you can write in Javascript. Being able to loop through an array or object is an essential skill all Javascript developers should have.
There is no one size fits all for loops, however you should know when you can & should use one over the other. You might be familiar with for
and while
, but perhaps the others listed here not so much.
The different types of loop we have in Javascript:
- for
- for..in
- for..of (added in ES6)
- forEach
- while
- do..while
For..loop
The essential basic loop every Javascript developer needs to know well. At its core a for loop is a recurring if statement that will continue provided condition 2 equals true.
1 |
for (condition 1; condition 2; condition 3) {
|
2 |
// Your code
|
3 |
} |
Condition 1 – Executed before the loop begins. Most commonly you will define a counter value and the overall length of the array you are iterating. This can be omitted in place of a semicolon if you have done the setup beforehand.
Condition 2 – This is the condition that dictates if the loop continues or not. You commonly will compare the current counter value to that of the overall length of the array. This is a true or false value, while the value equals true, the loop will keep running. This can be omitted in place of a semicolon forcing you to break the loop inside or you can end up with an infinite loop.
Condition 3 – This is run after each iteration of the loop. Most commonly you will increment a counter value here (probably in 99% of use cases). This value can be omitted in place of a semicolon as well (like when incrementing your loop from inside).
For..in Loop
The second most essential loop every Javascript developer should know. It allows you to iterate the properties of an object aka its keys. Lets view an example, shall we?
01 |
var person = {first_name: 'Dwayne' , last_name: 'Charrington' , age: 27, star_sign: 'Aquarius' };
|
02 |
03 |
// The below loop will output: |
04 |
// "Dwayne" |
05 |
// "Charrington" |
06 |
// 27 |
07 |
// "Aquarius" |
08 |
09 |
for ( var p in person) {
|
10 |
if (person.hasOwnProperty(p)) {
|
11 |
console.log(person[p]);
|
12 |
}
|
13 |
} |
You probably noticed that I am using a method called hasOwnProperty. This method checks whether or not the object has the specified property directly on its prototype, not an inherited value. Most Javascript linters will throw an error if you do not usehasOwnProperty
within your for..in loops.
For..of Loop
This is a recently new addition in ES6 and as such, it is not that well supported in browsers just yet. However, through the use of a transpiler, you can use it today without recourse.
The for..of loop is sort of the inverse of the for..in except that it iterates values & can only iterate over iterable objects of which Object is not a part of for obvious reasons.
1 |
var fruits = [ 'orange' , 'apple' , 'squash' , 'pear' ];
|
2 |
3 |
for ( var fruit of fruits) {
|
4 |
console.log(fruit);
|
5 |
} |
The beautiful thing about the for..of loop is that we can now finally get the values of an Array
for example without needing to write a long convoluted for loop, create a pointer and increment some kind of counter using a variable. It is arguably the cleanest way to get values out of an array.
forEach Loop
This is an interesting one because even though it is a loop, it can’t really be considered a traditional loop because it is somewhat limited in its use.
The forEach loop also only works with arrays, not objects. It has the added advantage of not requiring additional variables to be defined, thus polluting your scope, just a method.
Probably the most limited of the bunch and in the sense of a loop, probably not really a loop you need to know. Still, I find it useful and it is important you know your options when it comes to iterating over an array of items.
01 |
var fruits = [ 'apple' , 'banana' , 'orange' , 'grapes' , 'pear' , 'passionfruit' ];
|
02 |
03 |
// The three values on the callback function are: |
04 |
// element - The element being traversed |
05 |
// index - The current index of the item in the array starting at 0 |
06 |
// array - The array being traversed (probably mostly irrelevant) |
07 |
08 |
fruits.forEach( function (element, index, array ) {
|
09 |
console.log(index, element);
|
10 |
}); |
Sometimes you just want to simply iterate an array and get its values, modify them like jQuery gives us in the form of jQuery.each.
The only downside of a forEach is that you cannot break the loop. If you want to create a loop using ES5 syntax, there is Array.every which you can read about usinghere.
While Loop
The while loop is similar to a for loop, except it only accepts one argument and that is a statement that equals true or false. So if you remember earlier we have three conditions for our for loop, this would be condition 2.
While loops are generally regarded as the fastest form of loop, that is debatable. You cannot argue that they don’t look cleaner than other types of loop. And in certain situations they can be the fastest type of loop because they’re arguably a lot less complex.
In my experience the fastest kind of while loop is a decrementing while loop in which you take a value and subtract from it until you hit zero (which is falsey).
1 |
var i = 20;
|
2 |
3 |
while (i--) {
|
4 |
console.log(i);
|
5 |
} |
Do..while Loop
You don’t see the do..while loop being used all too much in favour of a straight for loop or while. You should know what the do while loop does even if you will never use it.
A while loop isn’t guaranteed to run. Meaning if you supply an expression to your while loop that equals falsey then it will not run. A do..while is guaranteed to run at least once.
But it doesn’t end there. A while loop executes its condition before the loop begins, the do..while executes the condition after the loop runs. Hence why a do..while is guaranteed to run at least once. The loop runs, the expression is checked and then so on.
Once again the Mozilla Developer documentation has an excellent articles on most of the loops touched upon here.
Basic methods & tasks
There are basic methods in Javascript you really should be aware of. From working with arrays to strings, Javascript contains a treasure chest of useful methods. We only touch upon methods for working with strings and arrays in this post, not objects or any other kind of value.
If you want to read more on working with various types of data in Javascript, the Mozilla Developer documentation is a nice and concise site for learning more about various methods.
Obviously some people will have opinions on whether or not you should know all of these and perhaps some I have left out. My memory can only stretch so far, but here are a few I think most developers should know. Knowing how to manipulate strings efficiently is an essential skill in my opinion.
Working with strings
In Javascript with exception of maybe working with arrays and objects, you will find yourself working with strings probably quite a bit. Even if you don’t really work with strings (or you think you don’t) knowing these basic methods for working with strings is an invaluable thing to commit to memory.
- String.replace(regexp|replaceThis, replaceWith|callback) – Allows you to replace a value with another value or even use a regular expression.
- String.concat(‘string1’, ‘string 2’, etc…) – This method allows you to concatenate one or more string values together.
- String.indexOf(value) – This method allows you to find the first occurrence of the specified value, or –1 if not found.
- String.slice(startIndex, endIndex) – This method does what it says. It will take a starting index (from zero) and an ending index value and return a new string with that chunk.
- String.split(separator, limit) – This method will split a string into an array comprised of one or more items.
- String.substr(startIndex, length) – This method will return the characters in the string starting from the startIndex value and only the specified length.
- String.toLowerCase – This method will return the specified calling string value as all lowercase.
- String.toUpperCase – This method will return the specified calling string value as all UPPERCASE.
- String.trim – Whitespace from the beginning and end of the calling string will be removed.
Working with arrays
During day-to-day development, I find myself working with arrays a lot. They serve as a great way to store data, to keep track of states and using them as maps generally.
I think knowing how to do basic tasks with arrays is an essential skill for a Javascript developer to have. Things you should not have to really Google.
- Array.pop – Removes the last element from an array and returns it
- Array.shift – Removes the first element from an array and returns it
- Array.push(val1, val2…) – Add one or more items to the end of an array. This method will always return the new array length after it is run. You can specify multiple comma separated values.
- Array.reverse – Reverses the order of an array (the first element becomes the last and the last one becomes the first, etc).
- Array.sort([compareFunction]) – Allows you to sort an array by specifying a compare function which has access to each value in the array you can sort on.
- Array.join(separator) – This method takes one or more items in the array and returns a string of values joined by their separator. If you don’t specify a separator, the default is a comma.
- Array.indexOf(value) – This method allows you to find the first occurrence of the specified value, or –1 if not found.
There are other methods for working with arrays not listed here which you should definitely read upon further. There are some exciting new methods that were added in ES6 not listed here and other array methods that go into more specific use cases.
Difference between Call and Apply
These two methods are misunderstood and intimidate a lot of developers. While it is possible to go without using call or apply, they are especially handy because they allow you to call methods and change what the context of the this
value is during execution.
The difference between the two is only subtle, but there is a difference. Using thecall
method will allow you to provide infinite comma separated arguments when calling a function.
Using the apply
method will allow you to call a method using an array as the supplied arguments. The method is great if you want to use an array as arguments on a method call as well as change the context of this
.
If you are just wanting to use an array of values as arguments on a function, ES6 comes to the rescue in the form of a spread operator. It doesn’t allow you to change the context of this
, but it does allow you to use an array of values as arguments.
An example using .call:
1 |
function myFunc() {
|
2 |
console.log(arguments);
|
3 |
} |
4 |
myFunc.call(this, 1, 2, 3, 4, 5); |
An example using .apply:
1 |
function myFunc() {
|
2 |
console.log(arguments);
|
3 |
} |
4 |
myFunc.apply(this, [1, 2, 3, 4, 5]); |
The new additions to ES6 mean there are really limited instances where we will need to use call or apply in the future. Thanks in part to spread operators, arrow functionsand the ability since ES5 to use bind.
Familiarity with frameworks/libraries
These days the biggest contenders in the Javascript framework race appear to be AngularJS, React.js and Ember. There are of course millions more, but these are the biggest and currently most popular (in my opinion).
As web applications grow in complexity, these frameworks and libraries make our lives easier. It is not unreasonable to expect that a Javascript developer in 2015 should know at least one framework or library other than jQuery.
Almost any job listing you look at searching for a front-end/Javascript developer will most likely mention a framework or two as a requirement or nice-to-have skill. Don’t get left behind.
Node.js
Without-a-doubt Node.js has proved its worth and shows no signs of falling by the wayside (unless IO.js kills it). Pretty much every front-end tool is built upon it and uses the Node Package Manager (NPM), if you have been holding off learning Node.js, you should reconsider.
Because Node.js is Javascript at its core, the learning curve is non-existent if you already no a little bit of Javascript. You will find you spend more time configuring packages you are using in your apps than you do learning Node.js.
I personally think Node.js is a skill every developer needs to have in 2015. I am not talking overly complex in-depth knowledge of it, but enough to use it for development servers, prototyping, testing and other use-cases where Node.js will be beneficial to your work-flow.
There is of course the fork of Node.js called IO.js which at present is exactly the same. At the end of the day, you’re just writing Javascript, albeit with a few small differences.
Testing
Once upon a time we didn’t really test Javascript code, it wasn’t something that many thought was necessary because lets face it: things never used to be that pretty or complicated. The language has grown inherently complex thanks in part to front-end frameworks like AngularJS and server side Javascript in the form of Node.js.
As Javascript evolves and code-bases swell as we use it for more and more things, testing becomes important, if not vital. If you aren’t testing your code in 2015, you’re doing it wrong.
My favourite test runner is definitely Karma. There are plenty of others to consider, but Karma is especially great for testing AngularJS applications. And if it’s good enough for AngularJS, it is good enough for me.
Tooling
Being a Javascript developer in 2015 means knowing how to use task runners, transpilers, profilers and other tools we have at our disposal to write the best Javascript code possible.
Sometimes the tools bundled within our browsers while good don’t always accurately depict what is going on inside your application. Sometimes you need to use a dedicated tool to get more detailed information about the inner workings on your application.
Tools to look into (if you don’t already use them); Gulp, Webpack and BabelJS. There are a lot of tools out there, task runners like Gulp and even Grunt are particular great additions to a modern Javascript heavy work-flow (if you don’t already use them).
Gone are the days of downloading a single Javascript file and including it into our page. These days package managers like NPM and Bower are used in place of manually downloading scripts.
We combine and minify scripts using task runners, test using separate tools and things are generally more organised.
Javascript tooling goes hand-in-hand with the likes of writing isomorphic Javascript (shared code-base between the server and front-end).
ECMAScript 6 aka ES6 aka ESNext
Even though browser support still has a while to go before most of the good parts of ECMAScript 6 are supported, we can use transpilers to start writing ES6 code today.
Familiarise yourself with all of the new API’s and methods around; strings, arrays and other cool features like WeakMaps, Symbols and Classes. Being a developer in 2015 means staying up-to-date with what is changing within the Javascript language.
Familiarise yourself with the concept of classes especially. They are merely syntactical sugar over the top of prototypical inheritance (for the moment), but there are plans to evolve classes in ES7 and beyond to make them more useful and less sugary.
The “noscript” tag
It is no secret that Javascript has become a first-class citizen of modern web application development. To the point where you would be hard-pressed to find a a modern web application or website that didn’t use Javascript.
But as we use Javascript for more and more things, some of us forget that not all browsers have Javascript enabled because of personal preference or use of a browser addon like NoScript.
If you’re developing a Javascript intensive application, as a common courtesy remember that not every visitor might have it turned on or more weirdly not have a browser that supports it (like a command line browser).
Further Reading
There are plenty of great resources out there for learning deeper parts of Javascript, many much better and insightful than this post.
- You Might Not Need jQuery
- Mozilla Developer: Javascript Reference & Guide
- JS: The Right Way
- AirBnb’s Javascript Styleguide
Conclusion
There are plenty more things I could go on about. Evident by how big this post is, there is a lot expected of a modern Javascript developer. This post is really only scratching the surface.
Please do not take this as gospel or the ultimate list of things Javascript developers should know. But having said that, there are certain things that all Javascript developers should know and as such, this article is my personal opinion.
If you have any improvements or see anything that can be expanded upon or added, please feel free to comment and let me know below.