Daniel Matthew HTML, CSS, and JavaScript developer

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 you need that functionality.

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.

Why does that equal this?

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

JavaScript has function scope. When a function is executed inside another, we no longer have access to the original value of this, as it has been assigned to the global scope, or if running in strict mode - and you should - it will be undefined. By aliasing it, we are able to retain a reference to this original value - and save some headaches along the way.

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

By convention we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specifications which causes this to be set incorrectly for inner functions.

However, we should be cleverer than this, and take advantage of the functionality that JavaScript gives us with .call, .apply, and .bind.

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

Closures 101

I updated this post on the 16th February in order to clarify my writing and thoughts.

What is a closure?

In computer science: > a closure is a first-class function with free variables that are bound in the lexical environment. Such a function is said to be “closed over” its free variables. A closure is defined within the scope of its free variables, and the extent of those variables is at least as long as the lifetime of the closure itself.

A higher-level definition is that > A closure is a function defined within another scope that has access to all the variables within the outer scope.

And just in case, think of it as: > …like keeping a copy of the all the local variables, just as they were when a function exited.

Closures are a strange concept to get to grips with, but once this core concept is understood they’re relatively easy to understand: a closure is created when a developer accesses variables outside of the immediate lexical scope.

An example of a closure in action

function makeAdder(a) {
  return function(b) {
    return a + b;
  };
}

x = makeAdder(5);
y = makeAdder(20);

x(6); // 11
y(7); // 27

JSFiddle demo

What happens in a closure?

When makeAdder is called, a new scope is created with one property: a - the argument passed to the function. It also returns the anonymous function declared within it. This returned function maintains a reference back to that original scope. This scope will persist and escape being garbage collected until there are no more references to that function.

Take a look at what happens when we log x:

function(b){
  return a + b;
}

So when we call x and pass an argument, that’s going straight into the anonymous function makeAdder returned the first time. Because we know a closure is a combination of a function and its scope

Since we are then able to all y, we discover that we have ended up with two different copies of makeAdder’s local variables: one in which a is 5, and another where a is 20.

When would I use a closure?

The technique is often used to prevent against contaminating higher levels of scope - data is kept tucked away. Along these lines, a closure can be used to help practise encapsulation: an object can return its public methods and variable, while keeping those intended to be private hidden and inaccessible to the rest of the codebase.

You may have taken advantage of one without realising it, as they’re a key concept when implementing an ‘Immediately-Invoked Function Expression’ (IIFE). Using an IIFE within a module, as per the Module Pattern, ensures that the module is self-contained.

An intelligent developer will > use closures to create additional scopes that can be used to group interrelated and dependent code in a way that minimises the risk of accidental interaction.

Useful reading

Get The Day Of The Week In JavaScript

var now = new Date();
var day = now.getDay();
// 1 (Monday)

It might not straight up give us “Monday”, but it’s a useful method to know.

Event Delegation In JavaScript

First, some markup:

<ul id="list">
  <li id="item-1"></li>
  <li id="item-2"></li>
  <!-- A little while later - hope this is automated! -->
  <li id="item-99"></li>
  <li id="item-100"></li>
</ul>

What is event delegation?

In the example above, it’s inefficient for both the browser and the developer to write event listeners for a large number of elements - particularly if these elements are being generated dynamically. Event delegation entails attaching a single listener to the parent element, then checking the target element as it bubbles up through the document structure.

What are the advantages?

Writing less code, for one, and less code means fewer opportunities for bugs to arise. It also means that when elements are removed, we don’t run into the risk of forgetting rid ourselves of their event listeners. Too many of those floating around in memory - particularly in complex web applications - can cause problems for the browser.

How do I implement event delegation?

Here’s a no-frills example:

document.getElementById('list').addEventListener('click', function(e) {
  if (e.target) {
    console.log(e.target.id); // Prints item id
  }
});

See this example in action

JavaScript Feature Detection

Some JavaScript features just don’t work in certain browsers. While it used to be a common practice to ‘sniff’ the user-agent string of the browser, this is now frowned-upon. The preferred approach is for developers to implement feature detection. That is, testing the ability of the browser to carry out the desired task. If the feature is not supported, we write our code intelligently in order to cater for this eventuality.

In Mark Pilgrim’s Dive Into HTML5, he documents a selection of techniques: - Checking for the existence of a property on a global object - Creating an element and checking for the property on that - Calling a method on a generated element and examining the value it returns - Setting a property on an element to a particular value and checking to see whether it has retained this value

A common example of the first technique is when writing an AJAX function:

var xmlHttp;
if (window.XMLHttpRequest) {
  xmlHttp = new XMLHttpRequest();
} else {
  // Figure out which ActiveX control to set up for Internet Explorer
  var XmlHttpVersions = new Array(
  'MSXML2.XMLHTTP.6.0',
  'MSXML2.XMLHTTP.5.0',
  'MSXML2.XMLHTTP.4.0',
  'MSXML2.XMLHTTP.3.0',
  'MSXML2.XMLHTTP',
  'Microsoft.XMLHTTP');
  
  for (var i = 0; i < XmlHttpVersions.length && !xmlHttp; i++){
    try {
      xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
    } catch(e) {
      // Here be dragons
    }
   }
  }

Thankfully, libraries such as Modernizr can be implemented in order to reduce the amount of boilerplate that needs to be written. It has an API that can be queried to easily check for feature support. If they’re not present, we can write a fallback so that the user’s experience isn’t compromised:

// Determine if font-face is supported
if (Modernizr.fontface) {
  // Do something
} else {
  // No fancy fonts
}

References

Ensure A Table Fills Its Containing Element

table {
  table-layout: fixed; // Default is auto
}

I was wondering what the correct CSS property was to control this requirement. Setting a width on the table element was doing precisely zip. That is until we set the above.

Loops in Sass

Sass makes it dead simple to automate repetitive tasks we might encounter when writing CSS.

Sass ‘For’ loop

@for $i from 1 through 100 {
  .box:nth-child(#{i}) {
    // Properties
  }
}

Sass ‘Each’ loop

@each $member in john, paul, george, ringo {
  .bandmember.#{$member} {
    background url("images/#{$member}.png");
  }
}