5 Minute JavaScript #16: map

Last week we took a look at the filter functionality. This week I will show you one of my favourite array methods called: “map”. It’s extremely powerful and useful in so many ways. The purpose of map is simple, it transforms an item in an array and pushes that transformation into a new array. The method then returns that newly created array with all the transformed items. A simple example will show you what it does.

var square = function (item) { return item * item; };
var squares = [1, 2, 3, 4].map(square);

In this example we just square a number in the array. The result will be a new array but with the squared items.

This example is easy to understand, but you might wonder what the practical use is for this function. Well in a lot of applications I find myself using map to select the identifier from an object and pass along a map of id’s.

var user = { id: 'UUID', version: 0, name: 'User 1' };
var users = [/* a list of users */];
var ids = users.map(function (u) {return u.id;}); 
var versions = users.map(function (u) {return u.version});
var idsAndVersions = users.map(function (u) { 
    return { 
        id: u.id, 
        version: u.version 
    };
});

These lists can be used in frameworks, api’s, ajax requests, caching, etc… everywhere you don’t need to know / send the full information of the user.

5 Minute JavaScript #15: filter

In the previous blogpost we discussed the forEach method that iterates over every array. We can now create a filtered array by using this function.

var filtered = []
arr.forEach(function (item) { if (item.isOkay) filtered.push(item); });

While this will work fine, we still need to predefine our filtered array and push it in this array ourselves. We don’t need to… we could just use the filter method on the array prototype.

var filtered = arr.filter(function (item) { return item.isOkay; });

This code isn’t only more readable and a little shorter, it also allows you to chain these methods. Also, you can use abstract validation functions to reuse the filtering.

var isEven = function (number) { return number % 2 === 0; };
var filtered = [1, 2, 3].filter(isEven);

A more practical example:

var stockItem = { category: "toys" /*, and other properties */ };
var stockItems = [/* has a bunch of stockitems with different categories */];

var product = { category: "toys", stockItems: [] };
var products = [/* has a bunch of products */];

var belongsToToyCategory = function (item) { return item.category === "toys";  };

var filteredStockItems = stockItems.filter(belongsToToyCategory);
var filteredProducts = products.filter(belongsToToyCategory);

5 Minute JavaScript #14: forEach

After discussing how to create a range in the last post, we will discuss some of the array methods and how to use them to make your code more readable and concise.

First of all, I want to add that every array method uses the callback pattern. We’ll do a post on this pattern later, when discussing Asynchronous JavaScript, but for now you need to know that callbacks in these functions are called for every item in the array.

The easiest array method is called forEach and will just iterate over every item in the array.

	[1, 2, 3].forEach(function (item) { console.log(item); });

Most people will recognize this method. It iterates over every item and does nothing with the return value you provide. What most programmers don’t know is that you have some additional features in forEach.

	[1, 2, 3].forEach(function (item, index, array) { this.log(item);  }, console);

The forEach function lets you set the functions context (= this, more later) as well. In the previous example I injected console as the ‘this’ value in callback function.

But beware:

	function hasNumber (arr, number) {
		arr.forEach(function (item) { 
			if (item === number) return true; 
		});
	}

While this code might look okay, you must know that JavaScript’s forEach is still a callback function. Returning the value true inside the callback won’t result in the global function (hasNumber) to return true. You should refactor this code to

	function hasNumber (arr, number) {
		var found = false;
		arr.forEach(function (item){ if (item === number) found = true; });
		return found;
	}

By using the some-method you will get an even easier result, but more about that in a future post.

5 Minute JavaScript #13: How to create an array from a range

Previous blogpost we discussed extending native data types in JavaScript. Today we’ll create a method in the array prototype that you can use to easily create a range such as an array.

Some programming languages allow you to easily create an array from a range, such as:

Scala

	val list = 0 until 10 toList

or Ruby

	arr = [0..10]

In JavaScript however, you need to use a for-loop to fill an array with ranged values. You could create a function that returns a filled array based on a from and to value like this:

function fill (from, to) {
 var a = [];
 for (var i = from; i <= to; i += 1) {
   a.push(i);
 }
 return a;
}

But then you have declared a function fill globally; that doesn’t really say much… it would be syntactically more interesting to use the Array prototype like this:

Array.prototype.fill = function (from, to) {
 var a = [];
 for (var i = from; i <= to; i += 1) {
   a.push(i);
 }
 return a;
};

Now we can create a new array using a very simple syntax

	var arr = [].fill(1,5); // results in [1,2,3,4,5]

While not perfect, defining the fill function this way, is a lot more readable. You start with an empty array and you fill it with a range of values. This makes perfect sense.

5 Minute JavaScript #12: extending native functionality

In the previous blogpost we took a quick look at the prototype of a value in JavaScript. We also noted that primitive data types such as String and Object have prototype objects of their own. JavaScript allows you to extend these prototype objects with.

A useful example is to add formatting functionality to the String prototype. JavaScript does not have a format function on String, even though this functionality is very useful. So, let’s add it ourselves.

String.prototype.format = function () {
   var str = this;
   for (var i = arguments.length - 1; i <= 0; i -= 1) {
       str = str.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
   }
   return str;
};

Now we can format strings like this

var template = 'Hello {0}, my name is {1}!';
var receiver = 'Tom';
var sender = 'Steve';
console.log(template.format(receiver, sender));

We can also rewrite functionality that we don’t like. For example, remember the time everyone debugged JavaScript with alert? People still tend to do this just because they are used to doing it. Even some frameworks are intrusive enough to show you an alert message when you make an error. That’s not really something we want. We can overwrite the alert functionality on the window object because… why wouldn’t we?

window.oldAlert = window.alert;
window.alert = function(message){
   // check if console exists
   if (typeof console === 'object') {
       // logs the alert instead of showing it
       console.log('[ALERT] '+message);
   } else oldAlert(message);
};

However, always make sure that you keep a reference to the old implementation!

5 Minute JavaScript #11: Prototypes

Last week, we discussed the JSON format. Today we are going to take a deeper look in the object structure in JavaScript. In most object-oriented programming languages you have some kind of classical inheritance. This means that the language allows you to define a sort of blueprint of an object named a class. JavaScript doesn’t work with these concepts. Instead, it works with prototypes. The dynamic nature of JavaScript allows you to apply inheritance on object level instead of class level. Every object has a prototype object, you can set this prototype object and automatically you will be able to access properties or functions on the child object.

var parentObject = { x:1, y: 1 };
var childObject = { x: 2, a: 2 };
childObject.prototype = parentObject;

In the example above, the childObject has three properties: x, y and a. Whenever JavaScript is interpreted, the interpreter selects the first instance it finds of a property/function. So if we would look for the property x on childObject, we would find 2 instead of 1 because the childObject’s x definition is the first one the interpreter encounters.

In JavaScript native types also have a prototype object. That prototype contains all the methods you can use on the type. For example the String type has a prototype object that contains the following methods:

  • String.prototype.charAt()
  • String.prototype.slice()
  • String.prototype.trim()
  • String.prototype.split()
  • String.prototype.toUpperCase()

These prototype methods are easy to use, you can just call them from the object, e.g. “lowercase”.toUpperCase(). Not only the String type has these methods, also Object, Array, Number and even Function!

var char = 'my string'.charAt(0);

We use these prototype functions every day and the fun thing is that we can create our own. But that’s for the next blogpost.

5 Minute JavaScript #10 JSON

This week we’re taking a break from complex code structures (like modules in the previous issue) and we get back to basics. JSON is a lightweight data-interchange format. Easy to read/parse but also to write/generate. It’s related to the way we notate objects in JavaScript, that’s why it’s called JavaScript Object Notation. Visit the website: http://json.org/ for complete information about JSON.

An example of a JSON object

{
    "str": "string",
    "bool": false,
    "obj": {
        "arr": [ 1, 2, 3, "string", false ]
    }
}

JSON is a popular way of formatting data when dealing with REST services. Whenever you are generating data (at REST level at the back-end) for web applications, you know that your data will be read and parsed by JavaScript. What better format for JavaScript to parse than its own object notation? This is why JSON is such a great way to interchange data. It’s lightweight, fast, easy, readable…

There are also some useful tools that you can use regarding JSON. http://jsonlint.com/ for example checks if your JSON-string is formatted correctly. http://json-schema.org/ describes your JSON-object in a way very similar to XML-schemas.