Daniel Matthew HTML, CSS, and JavaScript developer

bind()

bind() was introduced in 2009’s ECMAScript 5 (ES5) specification. It can be used to perform a “partial function application”. A new function is created that calls the original, and specifies a number of new arguments.

function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5

In an example similar to that above, bind() is used to create a new function that is takes add(), but only requires one parameter, as y is always 1:

function add(x, y) {
  return x + y;
}

var plus1 = add.bind(null, 1);
console.log(plus1(5)); // 6

this and that in JavaScript

When looking at code written by others, you may wonder why JavaScript developers will often alias this as that, or self, within a function. Why is this? Surely this always refers to the current object?

Short story: nope.

What’s this?

Unlike other languages where it refers to values stored in instance properties, the this keyword is dynamically bound based on how a particular function is executed. Because of its shifting nature, it can be tricky to keep track of what this might be referring to when it is called. With a little understanding of the rules behind this, we can be more confident when writing our code.

There are four rules that help us figure out what this may be at a particular point in time, and these rules are based on the call-site of the function.

1: Default Binding

When our function is invoked of its own accord, ala:

function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // 2

The call to this.a resolves to the global variable of the same name. If we were running in strict mode - and you should - we would find that it would be undefined:

function foo() {
  console.log(this.a);
}

var a = 2;

foo(); // 'this' is undefined

2: Implicit Binding

When calling a function as an object method, its call site now has some context and the object in question should be used for the function’s this binding.

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
  foo: foo
};

obj.foo(); // 2

3: Explicit Binding

We can use the call() and apply() utilities to force a function to use a particular object for its this binding. For both utilities, the first parameter is the object to use. As we’ve discovered previously call() takes a list of parameters, while apply() is given an array as its second argument.

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

foo.call(obj); // 2

Hard Binding

Both implicit and explicit binding lose their this binding when passed around. The following pattern helps ensure that this doesn’t happen:

function foo() {
  console.log(this.a);
}

var obj = {
  a: 2,
};

var bar = function() {
  foo.call(obj);
};

bar(); // 2
setTimeout(bar, 100); // 2

The new bar() function calls foo() with this bound to our object. bar() can be passed around, as it is to setTimeout(), and yet this remains 2.

It might get a little tiresome wrapping functions for this purpose, so ES5 (supported natively in IE9+, or with ES5-shim) gives us bind(): a utility that returns a new function that calls the original, with this set as required.

function foo(something) {
  console.log(this.a, something);
  return this.a + something;
}

var obj = {
  a: 2,
};

var bar = foo.bind(obj);

var b = bar(3); // 2 3
console.log(b); // 5

4: new Binding

When using new to create a new object, the new object is set as the this binding.

function foo(a) {
  this.a = a;
}

var bar = new foo(2);
console.log(bar.a); // 2

So, if the function is called:

  • with new, this is the new object;
  • using call, apply, or bind, this is the specified object;
  • as it being a method of an object, this is that object;
  • in standard execution, this is either the global object, or will be undefined if using strict mode.

Why that, then?

Each function call gets its own this binding. When a function is executed inside another, we no longer have access to the original this value. By aliasing it as that or self at the top level, we can retain a reference to the original value and make it visible to inner functions.

As for the reasoning behind this convention, Douglas Crockford states that:

…This is a workaround for an error in the ECMAScript Language Specifications which causes this to be set incorrectly for inner functions.

While it’s a useful trick to have in the toolbox, JavaScript does give us utilities to avoid having to use it in the first place. We can take advantage of the functionality JavaScript gives us with call(), apply(), and bind() in order to explicitly tell a function the context it will be running in.

setTimeout and setInterval

JavaScript features a couple of useful utilities that allow the developer to schedule code to run outside of the normal execution flow.

setTimeout

In order to run a function after a specific delay, we use setTimeout():

function doSomething(message) {
  console.log(message);
}

var myTimeout = setTimeout(doSomething, 2000, "lol");

// Two seconds later...
// lol

Timeouts can be cancelled using clearTimeout() and passing the ID of the timeout in question. In the above example, to prevent our applicating from printing lol, we could set up a button which called clearTimeout(myTimeout).

setInterval

If you want to call a function repeatedly, setInterval() is the more appropriate tool. It looks very similar:

function doSomethingElse(message) {
  console.log(message);
}

var myInterval = setInterval(doSomethingElse, 5000, "See you in five...");

// Every five seconds...
// See you in five...

As with timeouts, we can run clearInterval() to call a halt to proceedings when we are done with it.

Debouncing

Imagine a searchbox that offers suggestions as you type. On each keydown event, a function is run that makes a network request. If the user enters a long query quickly, the browser (and remote server!) may quickly become overwhelmed and end up feeling unresponsive.

To overcome this, we can implement setTimeout() in order to debounce the event: we prevent it from happening too often. Instead of calling the function on each keypress, we wait for an opportune moment - perhaps a slight pause. When events occur closer than our timeout delay, the timeout from the previous keypress is cancelled and a new one is executed.

var myTextBox = document.querySelector('[type="search"]');
var myTimeout;

myTextBox.addEventListener("keydown", function() {
  clearTimeout(myTimeout);
  myTimeout = setTimeout(function() {
    // Query remote server
  }, 500);
});

Implementing Responsive Images

I’m hoping that you’ll notice the site - particularly my work section - is feeling a little snappier today: that’s because I took it upon myself to implement a solution for responsive images.

Take a look at this screenshot (also a responsive image, fact-fans): Before: Screenshot showing the network tab within Chrome's Developer Tools

Chrome’s Developer Tools are telling us that a request to /work had the browser download 3.4 MB over 13.77 seconds - on a fast ADSL connection. That’s pretty bad news for a visitor using a mobile phone on a cellular connection: whether it be the time needed for the page to finish loading, or if their provider imposes a data cap.

I have a confession: I was being pretty lazy. The images presented were simply screencapped in OS X and uploaded. I didn’t resize them or convert them from PNG-24 to a more pallatable format for the web. It’s not like I needed the transparency! In fact, I could probably go further: I could crop out the drop-shadow and browser chrome, and implement those additions with CSS.

There are a few options open to a developer wishing to implement responsive images:

The srcset attribute

srcset allows the developer to provide the browser with multiple resolutions of the same image.

<img srcset="/public/img/build/ribbonworks-new-full.jpg 1307w,
/public/img/build/ribbonworks-new-med.jpg 654w,
/public/img/build/ribbonworks-new-small.jpg 327w" 
src="/public/img/build/ribbonworks-new-full.jpg" 
alt="Ribbonworks.co.uk" />

The srcset attribute is simply a comma-separated list of URIs and a “width descriptor”, which is used by the browser as part of its decision-making process.

The picture element

The new picture element in HTML allows the developer to implement ‘art-direction’: they can choose the image displayed at a particular breakpoint. My screenshots are all of a desktop browser. I could use the picture element to display these images as they appear on mobile, or tablet browsers. The syntax is a slight departure from using img:

<picture>
  <source media="(max-width: 36em)" srcset="/public/img/build/ribbonworks-new-mobile-full.jpg 1307w,
/public/img/build/ribbonworks-new-mobile-med.jpg 654w,
/public/img/build/ribbonworks-new-mobile-small.jpg 327w" />
  <source srcset="/public/img/build/ribbonworks-new-full.jpg 1307w,
/public/img/build/ribbonworks-new-med.jpg 654w,
/public/img/build/ribbonworks-new-small.jpg 327w" />
  <img src="/public/img/build/ribbonworks-new-full.jpg" />
</picture>

The developer provides source elements and an img. The browser evaluates the sources until the parameters provided in media attribute are true. The srcset from this source is then applied to the img.

Processing Images

The main obstable to implementing this isn’t browser support (there are multiple quality polyfills, such as Picturefill), but actually creating multiple versions of each of your images. I ended up using Photoshop and saving each file out at 50 and 25 percent. In doing so, I encountered its “Extract Assets” feature which would make the process a cinch - if its output matched my workflow. I’d looked at ways of automating it, and found several Grunt plugins, including grunt-responsive-images, though I got turned off at the need to install Imagemagick. Adding this functionality to a platform such as WordPress would be seemingly trivial - again, so long as a module such as Imagemagick is installed. WordPress already has the ability to process images and create multiple sizes for different roles.

Results

Simply converting my portfolio images to JPEG reduced the required bandwidth down to 1.5 MB: a 42% reduction. As Kevin Bacon would say: “a no-brainer”. By taking advantage of srcset and providing scaled-down versions of the images, the site loaded in just 2.66 seconds, and only transferred 522 KB: After: Screenshot showing the network tab within Chrome's Developer Tools

Worthwhile reductions methinks, and this just on a small site. If I were serving many thousands of impressions a day, I know that this would be one way to keep my bandwidth costs down, alongside making the browsing experience more tolerable for everyone.

last-child in CSS

The :last-child psuedo-selector allows the developer to target the last child element of its parent. But you need to qualify it with the element that you are targetting. Something that has caught me out in the past has been applying the selector to the parent itself:

/* Nope - this won't work and you'll feel silly */
ul:last-child {
  border-bottom: none;
}

It kind of makes sense, right? I want the last child of that unordered list. But no: pseudo-selectors, such as :last-child, :hover, and :checked work on the state of the specified element.

In the common scenario of wanting to style the last element in a list differently, you can use the following code example:

li {
  border-bottom: 1px solid #f3f3f3;
}

li:last-child {
  border-bottom: none;
}

When that list element finds itself as the :last-child of its parent, the browser will remove its border.

JavaScript's 'let' keyword

Good news everybody! ES6 (or ES2015) introduces the let keyword. This allows the developer to attach a variable to the scope of whatever code block - code between { and } - it resides in. Block scope rather than function scope!

JavaScript Constants

The new ES6 JavaScript standard finally allows developers to declare variables using the handy const keyword. This prevents the value from being reassigned - somewhat reassuring if that’s a requirement.

That said, values declared with const can still be modified after the fact: they’re not immutable. If you’re after that particular bit of functionality, you can still fall back on the .freeze property that objects have access to. If you’re using strict mode - and why not? - you’ll receive a TypeError, unless you look to see whether the object .isFrozen.

Shadowing And Hoisting In JavaScript

Shadowing

To “shadow” a variable is to create a new variable with the same name as one that exists in a higher scope. In JavaScript, a new scope is created when writing a function. When resolving a variable, JavaScript starts at the innermost scope and searches outwards.

Hoisting

Hoisting, on the other hand, is a behaviour which results in variables being raised, or ‘hoisted’, to the top of the scope - the function - in which they have been defined. It’s recommended to declare all of your variables at the top of a function in order to avoid overwriting a value.

Checking Date Equality in JavaScript

Checking whether one date is equal to another is made difficult because of the way object equality works in JavaScript. Object equality isn’t tested by the internal value of the object, but by identity. If the date object isn’t a straight copy, it isn’t considered equal. The following example will never return true:

function isChristmas(dateToTest){
  var christmas = new Date("12/25/2014");
  return (dateToTest === christmas);
}

console.log(isChristmas(new Date("12/25/2014"))); // False

To make the isChristmas function work, we need to check equality in a different way. We use the getTime method that is available on Date object, and compare the values it returns. getTime returns an integer representing the number of milliseconds since midnight of the epoch: January 1st, 1970.

function isChristmas(dateToTest){
  var christmas = new Date("12/25/2014");
  return (dateToTest.getTime() === christmas.getTime());
}

console.log(isChristmas(new Date("12/25/2014"))); // True

But! If we happen to compare against a Date object that occurs on the same day, but a different hour, we’ll run into trouble - because the time elapsed since the epoch will be different.

A work around here might be to check our date against the year, month and day, like so:

function isChristmas(dateToTest){
  return (dateToTest.getFullYear() === 2014) &&
  (dateToTest.getMonth() === 11) &&
  (dateToTest.getDate() === 25);
}

console.log(isChristmas(new Date("12/25/2014 12:00"))); // True

But then this is glossing over the complexities that daylight savings and timezones introduce.

TL;DR: Be aware that there are ‘gotchas’ when comparing dates. Use Moment.js to avoid them and make your life easier.

Substring, Substr, and Slice.

When dealing with strings in JavaScript, there are several options available when needing to return a particular section:

Substring

This function can accept two parameters: the first an integer between 0 and the length of the string; the second an integer between 0 and the length of the string. substring returns a subset of a string between one index and another, or if the second parameter is omitted, through to the end of the string. A useful feature of this implementation is that if the first parameter is larger than the second, the effect of substring will be as if the arguments were swapped.

Substr

substr is a variant of substring. The difference here is that while the first parameter defines the first character, the second specifies the number of characters to return.

Slice

Both arrays and strings boast a slice method. The arguments it will accept are integers to define the the start and end points of the extraction. Again, if the end point is omitted, the function will keep going until the end of the string. A benefit is that the second argument can be a negative value, which will allow the operation to begin counting from the end. On top of this, slice will return a new string.

References