Testing Array Contents with Array

Originally published in A Drip of JavaScript.

When working with arrays, it is quite common to perform different actions based on whether or not the array contains a particular item. A fairly straightforward implementation of this pattern can be found below:

planets = [
    "mercury",
    "venus",
    "earth",
    "mars",
    "jupiter",
    "saturn",
    "uranus",
    "neptune"
];

// Default to false
var containsPluto = false;

for (var i = 0; i < planets.length && !containsPluto; i++) {
    if (planets[i] === "pluto") {
        containsPluto = true;
    }
}

// Outputs: false
console.log(containsPluto);

Here our for loop is doing the work of iterating over the array, and a simple if statement checks to see if our condition is met yet. This for loop is a little more complicated than most because it is set up to stop iterating as soon as a matching element is found in the array.

While it is not that difficult to understand, manually keeping track of the iteration and the "short circuiting" logic just isn't the problem that we're trying to solve. The fewer such things we have to keep in our head, the better. We could fix this by moving the loop into it's own function (probably a good idea), but fortunately the latest version of the JavaScript standard includes such a function for us.

The function is called some and it is available on all arrays. Here is an example of how it would apply to our problem.

function isPluto(element) {
    return (element === "pluto");
}

// Outputs: false
console.log(planets.some(isPluto));

dwarfPlanets = [
    "ceres",
    "pluto",
    "haumea",
    "makemake",
    "eris"
];

// Outputs: true
console.log(dwarfPlanets.some(isPluto));

All we have to do to use some is to pass it a callback function. The callback will be executed once for each element until the callback returns true. At that point the some method itself will return true. If the callback never returns true, then some will return false.

The great thing about some, though is that you don't have to think about that unless you want to. You just have to pass in your callback.

In addition to the array element itself, the callback function has access to two other parameters: the current index, and the entire array. This can be useful in situations where you are comparing the current element against other members of the array. Consider this example:

function isLessThanPrev(el, index, arr) {
    // The first element doesn't have a predecessor,
    // so don't evaluate it.
    if (index === 0) {
        return;
    } else {
        return (el < arr[index - 1]);
    }
}

evens = [2, 4, 6, 8];
randoms = [0, 9, 2, 5];

// Outputs: false
console.log(evens.some(isLessThanPrev));

// Outputs: true
console.log(randoms.some(isLessThanPrev));

As with other features of ES5 that we've talked about, some is only supported in IE9 and higher. If you'd like to use it in older browsers, you will need to use a library like Underscore which has an equivalent method or a compatibility shim which ports Array#some back into older browsers.

Soon we'll be taking a look at what it takes to write your own compatibility shims.

Josh Clanton
http://designpepper.com

Published on


Using Dispatch Tables to Avoid Conditionals in JavaScript

Originally published in A Drip of JavaScript.

When writing code, one of the surest ways to keep things simple and straightforward is to avoid conditionals when possible. Unfortunately, it is fairly common to see code with a lot of if, switch, and case statements like the following:

function processUserInput(command) {
    switch (command) {
        case "north":
            movePlayer("north");
            break;
        case "east":
            movePlayer("east");
            break;
        case "south":
            movePlayer("south");
            break;
        case "west":
            movePlayer("west");
            break;
        case "look":
            describeLocation();
            break;
        case "backpack":
            showBackpack();
            break;
    }
}

Above we have a function for processing user input from a text adventure game. While it isn't terribly difficult to understand, it is more complicated than necessary. And as the number of commands grow, the function can quickly become unwieldy. So what can we do to simplify it?

var commandTable = {
    north:    function() { movePlayer("north"); },
    east:     function() { movePlayer("east");  },
    south:    function() { movePlayer("south"); },
    west:     function() { movePlayer("west");  },
    look:     describeLocation,
    backpack: showBackpack
}

function processUserInput(command) {
    commandTable[command]();
}

In this refactored version we are using a dispatch table to hold all the possible commands a user can give, and the functions the program should call. That changes the processUserInput function into a single line, and eliminates all conditionals.

If you are unfamiliar with bracket notation, it is just an alternate way of accessing a function's properties, with the advantage that you can use variables for the property's name. For example, if command is "north", then commandTable[command] is equivalent to commandTable.north.

The fundamental change we made is transforming the conditionals into a data structure. And data is much easier to manipulate than conditionals. In the future, if we want to add a new command, all we have to do is add it to commandTable. No messing around with case or break statements required.

If you enjoyed this issue of A Drip of JavaScript, share it on Facebook.

Thanks for reading!

Josh Clanton
http://www.designpepper.com

Published on


What are Prototype Properties and Methods?

Originally published in A Drip of JavaScript.

A couple of weeks ago, I mentioned prototype properties in passing. But what exactly are they? Let's take a look.

function Book(title, author) {
    this.title = title;
    this.author = author;
}

Book.prototype.getFormatted = function () {
    return this.title + " - " + this.author;
}

var hobbit = new Book("The Hobbit", "Tolkien");

// Outputs: "The Hobbit - Tolkien"
console.log(hobbit.getFormatted());

What is this magical getFormatted? And how did it get attached to my object? It's all through the power of prototypes.

Whenever you create an object using a constructor, that constructor has a property called prototype which points to an object. If you haven't done anything special, that prototype property is just an empty object. But it's an empty object with superpowers.

Let's see how that works.

function Book(title, author) {
    this.title = title;
    this.author = author;
}

Book.prototype.pubYear = "unknown";

var hobbit = new Book("The Hobbit", "Tolkien");

var caspian = new Book("Prince Caspian", "Lewis");
caspian.pubYear = 1951;

// Outputs: "unknown"
console.log(hobbit.pubYear);

// Outputs: 1951
console.log(caspian.pubYear);

// Outputs: "unknown"
console.log(Book.prototype.pubYear);

In the example above, we create a Book constructor, and then create a pubYear property "unknown" on it's prototype object.

When we try to access hobbit.pubYear, the JavaScript interpreter realizes that the hobbit object doesn't have a matching property, so it then checks to see if there is a matching property on the prototype object. Since there is, it will give us the value of Book.prototype.pubYear.

But because the caspian object has a pubYear property of it's own, the interpreter never has to go look at the prototype object.

While ordinary properties on a prototype can be useful, methods are more useful still. Let's go back to our original example.

function Book(title, author) {
    this.title = title;
    this.author = author;
}

Book.prototype.getFormatted = function () {
    return this.title + " - " + this.author;
}

var hobbit = new Book("The Hobbit", "Tolkien");

// Outputs: "The Hobbit - Tolkien"
console.log(hobbit.getFormatted());

Now you should know how the property lookup works. The interpreter realizes that there is no getFormatted property on hobbit itself, so looks for it on the prototype.

But you might notice something else special. The getFormatted method makes use of this.title and this.author. That works because when an object's method is invoked, the object itself becomes the this for the method. And that's even if the method itself belongs to the prototype rather than directly to the object.

Why bother with all of this, though? Why not define getFormatted directly on the object, like so?

function Book(title, author) {
    this.title = title;
    this.author = author;

    this.getFormatted = function () {
        return this.title + " - " + this.author;
    }
}

Because if you do it like that, rather than defining a single method which can be used by all Book objects, each object has its own copy of the method. Now imagine a scenario where you are producing lots of Book objects.

var bookArray = [ ]

for (var i = 0; i < 100; i++) {
    bookArray[i] = new Book("Some Title", "Some Author");
}

Now you have have 100 copies of getFormatted taking up space in memory. In addition, if you need to change how getFormatted works, you'll need to manually update each instance of Book. Compare that to how simple it is to update the prototype method.

function Book(title, author) {
    this.title = title;
    this.author = author;
}

Book.prototype.getFormatted = function () {
    return this.title + " - " + this.author;
}

var hobbit = new Book("The Hobbit", "Tolkien");

// Outputs: "The Hobbit - Tolkien"
console.log(hobbit.getFormatted());

// Oops! We need to use commas, not hyphens
Book.prototype.getFormatted = function () {
    return this.title + ", " + this.author;
}

// Outputs: "The Hobbit, Tolkien"
console.log(hobbit.getFormatted());

Updating the method on the prototype means that all instances of Book get the updated method immediately, and you don't have the possibility of some instances having the outdated method.

So those are the basics of how prototype properties and methods work.

Whew! That's a bit wordier than normal, but the newsletter should be back to a normal length next week.

Thanks for reading!

Josh Clanton
http://designpepper.com

Published on


Dealing with the Dangers of `this` in Constructors

Originally published in A Drip of JavaScript.

As I mentioned in the last issue, invoking a constructor without new can be dangerous. Let's go over why.

function Color(r, g, b) {
    this.r = r;
    this.g = g;
    this.b = b;
}

// Safe invocation
var red = new Color(255, 0, 0);

// Dangerous invocation
var blue = Color(0, 0, 255);

When a constructor is invoked with the new keyword, the this value of the constructor is set to the new object that you are creating. But when a constructor is invoked like a normal function, its this defaults to the same this variable that any other function gets. And normally that is the global object (window in the browser.)

Here is an illustration of the problem.

// Global variable
r = "Rodent Of Unusual Size";

function Color(r, g, b) {
    this.r = r;
    this.g = g;
    this.b = b;
}

// Dangerous invocation
// Means `this` is the global object
var blue = Color(0, 0, 255);

// Outputs: 0
console.log(r);

// Outputs: undefined
console.log(blue);

In the example above, there is a global variable named r. Or to put it another way, the global object has a property named r. When the Color constructor is invoked without new, the constructor's this is set to the global object (in most cases). Which means that the constructor function has just overwritten the global r variable with something that was intended to be a property of the blue object.

Furthermore, because Color was invoked as an ordinary function, it didn't automatically return a new object, which means that blue is also undefined.

As you can imagine, debugging an issue like this can be time consuming and frustrating. So how do we prevent these sorts of problems? Fortunately the answer is pretty straightforward.

// Global variable
r = "Rodent Of Unusual Size";

function Color(r, g, b) {
    // Check whether `this` is a
    // `Color` object.
    if (this instanceof Color) {
        this.r = r;
        this.g = g;
        this.b = b;
    } else {
        // If not, then we should invoke
        // the constructor correctly.
        return new Color(r, g, b);
    }
}

// Dangerous invocation
// Means `this` is the global object
var blue = Color(0, 0, 255);

// Outputs: "Rodent Of Unusual Size"
console.log(r);

// Outputs: Color {r: 0, g: 0, b: 255}
console.log(blue);

In the updated Color constructor, the first thing we do is check whether this is an instance of Color. It works because the new keyword will have already created the new object as an instance of the constructor before the constructor function begins running.

If it isn't a Color object, then we know the constructor was invoked incorrectly, so we skip all the construction logic and have Color return the results of correctly invoking itself with new.

This means that the constructor is no longer in danger of clobbering the global object's properties.

Of course, using this approach also means that developers may get into the bad habit of invoking constructors without new. If you'd rather just force them to always use new, you could throw an error instead, like so:

function Color(r, g, b) {
    // Check whether `this` is a
    // `Color` object.
    if (this instanceof Color) {
        this.r = r;
        this.g = g;
        this.b = b;
    } else {
        // If not, throw error.
        throw new Error("`Color` invoked without `new`");
    }
}

And that's how you can make your custom constructors safely deal with a missing new keyword.

Josh Clanton

Published on


Constructors in JavaScript

Originally published in A Drip of JavaScript.

Despite the fact that they are very powerful, constructors are one of the most underused features of JavaScript. (Probably because they have a very influential detractor.) But if you want to really know JavaScript, you'll need to learn how they work.

What is a constructor? It's an ordinary function that is used with the new operator to produce a specialized type of object.

// `Color` is a constructor
var red = new Color(255, 0, 0);

In this example, red is a new "Color" object. But how does that work?

function Color(r, g, b) {
    this.r = r;
    this.g = g;
    this.b = b;
}

var red = new Color(255, 0, 0);

As you can see, the Color constructor is merely taking the arguments given to it and attaching them to the this object. That's because when the constructor is invoked by new, the constructor's this is set to the object that new will return.

Which means that the code above is roughly equivalent to:

var red = {
    r: 255,
    g: 0,
    b: 0
};

So why would we use a constructor? There are a couple of important reasons.

First, using a constructor means that all of these objects will be created with the same basic structure, and we are less likely to accidentally make a mistake than if we were creating a whole bunch of generic objects by hand. (Especially if we make the constructor throw errors on invalid input.)

Second, using a constructor means that the object is explicitly marked as an instance of Color.

var red = new Color(255, 0, 0);

var blue = { r: 255, g: 0, b: 0 };

// Outputs: true
console.log(red instanceof Color);

// Outputs: false
console.log(blue instanceof Color);

That gives us a means to ensure that we are receiving the correct type of data to process.

Third, using a constructor means that we can easily assign specialized methods to the constructor's prototype, and they will instantly be available to all objects created by the constructor.

function Color(r, g, b) {
    this.r = r;
    this.g = g;
    this.b = b;
}

Color.prototype.getAverage = function () {
    var total = this.r + this.g + this.b;
    var avg = total / 3;
    return parseInt(avg, 10);
};

var red = new Color(255, 0, 0);
var white = new Color(255, 255, 255);

// Outputs: 85
console.log(red.getAverage());

// Outputs: 255
console.log(white.getAverage());

It is important to always use the new keyword when invoking the constructor. Otherwise the constructor may clobber the this which was accidentally passed to it. In most cases that is the global object (window in the browser or global in Node.)

Because of this danger, it is customary to capitalize a constructor's name so that others know to invoke it with new.

An upcoming article will deal with how to further mitigate the danger inherent in working with constructors.

Josh Clanton

Published on


Transforming Arrays with Array

Originally published in A Drip of JavaScript.

One of the most common tasks that developers perform in any language is taking an array of values and transforming those values. Up until recently, doing that in JavaScript took a fair bit of boilerplate code. For instance, here is some code for darkening RGB colors:

var colors = [
    {r: 255, g: 255, b: 255 }, // White
    {r: 128, g: 128, b: 128 }, // Gray
    {r: 0,   g: 0,   b: 0   }  // Black
];

var newColors = [];

for (var i = 0; i < colors.length; i++) {
    transformed = {
        r: Math.round( colors[i].r / 2 ),
        g: Math.round( colors[i].g / 2 ),
        b: Math.round( colors[i].b / 2 )
    };

    newColors.push(transformed);
}

// Outputs:
// [
//    {r: 128, g: 128, b: 128 },
//    {r: 64,  g: 64,  b: 64  },
//    {r: 0,   g: 0,   b: 0   }
// ];
console.log(newColors);

As you can see, there's quite a bit going on in that code that isn't really about what we want to accomplish, but is keeping track of trivial things like the current index and moving the values into the new array. What if we didn't have to do all of that?

Fortunately in ECMAScript 5 (the latest version of JavaScript), we don't. Here is the same example rewritten to take advantage of the map method:

var newColors = colors.map(function(val) {
    return {
        r: Math.round( val.r / 2 ),
        g: Math.round( val.g / 2 ),
        b: Math.round( val.b / 2 )
    };
});

Much nicer isn't it? Invoking map returns a new array created by running a transformation function over each element of the original array.

Now the only thing you need to keep track of is the logic of the transformation itself.

Of course, map isn't limited to simple transformations like this. Your function can also make use of two additional parameters, the current index and the array itself. Consider the following example:

var starter = [1, 5, 5];

function multiplyByNext (val, index, arr) {
    var next = index + 1;

    // If at the end of array
    // use the first element
    if (next === arr.length) {
        next = 0;
    }

    return val * arr[next];
}

var transformed = starter.map(multiplyByNext);

// Outputs: [5, 25, 5]
console.log(transformed);

As you can see, the additional parameters make it easy to create transformation functions which use the array element's neighbors. This can be useful in implementing something like Conway's Game of Life.

Browser support for map is pretty good, but not universal. It isn't supported in IE 8 and below. You have a few options for dealing with this.

  1. Don't use map.
  2. Use something like es5-shim to make older IE's support map.
  3. Use the _.map method in Underscore or Lodash for an equivalent utility function.

One of the most powerful techniques for avoiding programming bugs is to reduce the number of things that you are keeping track of manually. Array's map method is one more tool to help you do exactly that.

Thanks for reading! If you enjoyed this article, consider sending it to a friend.

Josh Clanton

Published on


What is an Array?

Originally published in A Drip of JavaScript.

For an experienced developer, that question may seem simplistic, but in the case of JavaScript the answer is rather interesting.

Conceptually, an array is just a list of values which can be accessed by using an integer as the "key". The list starts at 0 and goes up from there. If we were to describe that with JavaScript's object notation, it would look like this:

fakeArray = {
    0: "value 1",
    1: "value 2"
}

I feel like we're missing something. Oh, I know. It's that pesky "length" property.

fakeArray = {
    0: "value 1",
    1: "value 2",
    length: 2
}

That's looking suspiciously array-like. And, as I've mentioned before, this is precisely how the arguments object works. What I haven't mentioned yet is that this is also how real arrays work "under the hood".

That's right, in JavaScript arrays are just a specialized type of object built into the language. It's easy to tell this by looking at the behavior of objects and arrays.

fakeArray = {
    0: "value 1",
    1: "value 2",
    length: 2
};

// Outputs "value 1"
console.log(fakeArray[0]);

realArray = ["value 1", "value 2"];
realArray.text = "some text";

// Outputs "some text"
console.log(realArray.text);

As you can see, you can access an object's properties in exactly the same way as an array's. And you can give an array additional properties just like any other object.

What about all those special array methods like indexOf, slice, and sort? Turns out, they're just functions attached to the array object. (More specifically, they belong to the Array prototype, but that's getting ahead of ourselves.)

realArray = ["value 1", "value 2"];

// Outputs "0"
console.log(realArray.indexOf("value 1"));

realArray.indexOf = function() {
    return "I'll never tell.";
};

// Outputs "I'll never tell."
console.log(realArray.indexOf("value 1"));

In fact, given enough time, it is possible to reimplement almost all of the native array functionality purely in terms of manipulating objects.

Here's an example of reimplementing the push method:

fakeArray = {
    length: 0,
    push: function (val) {
        // Place the new value into the
        // next available integer key
        this[this.length] = val;

        // Update the length property
        this.length = this.length + 1;

        // Return the updated length
        return this.length;
    }
};

fakeArray.push("first value");
fakeArray.push("second value");

// Outputs "first value"
console.log(fakeArray[0]);

// Outputs "second value"
console.log(fakeArray[1]);

The one important thing that can't be reimplemented is the convenient array literal syntax for creating arrays. (The square brackets.) But you can always use a constructor instead. In fact, the following two ways of creating an array are exactly equivalent.

literalWay = ["value 1"];

constructorWay = new Array("value 1");

If you're willing to give up the literal syntax, you can rebuild the concept of arrays in JavaScript entirely from scratch to achieve something like this:

myCustomArray = new CustomArray("value 1");

And now you know (if you didn't already) how arrays work in JavaScript.

If you have other subjects you'd like to see covered in the future, drop me a suggestion. Thanks for reading!

Josh Clanton

Published on


Reordering Arrays with Array

Originally published in A Drip of JavaScript.

In last week's issue I briefly mentioned the standard sort method available on all JavaScript arrays. It does just what you'd expect.

// Produces [1, 2, 3]
[3, 2, 1].sort();

// Produces ["a", "b", "c"]
["c", "b", "a"].sort();

// Produces [1, 2, "a", "b"]
["b", 2, "a", 1].sort();

As you can see, it sorts by dictionary order (numbers first, followed by letters). But what if you want to sort your array differently? For example, listing "better" cars first? How would you go about that? Fortunately, sort accepts a custom comparison function.

var cars = [
    "Honda Civic",
    "Ford Taurus",
    "Chevy Malibu"
]

cars.sort(function(a, b) {
    // Default to 0, which indicates
    // no sorting is necessary
    var returnVal = 0;

    // If `a` is a Chevy, subtract 1
    // to move `a` "up" in the sort order
    // because Chevys are awesome.
    if (a.match(/Chevy/)) {
        returnVal = returnVal - 1;
    }

    // If `b` is a Chevy, add 1
    // to move `b` "up" in the sort order
    if (b.match(/Chevy/)) {
        returnVal = returnVal + 1;
    }

    return returnVal;
});

// Outputs:
// ["Chevy Malibu", "Honda Civic", "Ford Taurus"]
console.log(cars);

The comparison function compares two values and returns a number.

  • If it returns a negative number, a will be sorted to a lower index in the array.
  • If it returns a positive number, a will be sorted to a higher index.
  • And if it returns 0 no sorting is necessary.

When you pass sort a comparison function, that function will be called repeatedly and given different values from the array until the array has been completely sorted.

It is important to note that returning 0 does not guarantee that a and b will remain in the same order. It merely means that sorting is not necessary. JavaScript engines may choose to keep them in the same order, but that is not part of the language spec.

Thanks for reading! If you enjoyed this issue, why not subscribe to the newsletter?

Published on


Arbitrary Parameters with the arguments Object

Originally published in A Drip of JavaScript.

In last week's issue we discussed default parameters. That gives us some flexibility when working with parameters, but what if we want something that would accept as many arguments as we can throw at it? Say for example that we want to create a function which adds together all the arguments we pass to it. How would we go about that?

function addAll () {
    // What do we do here?
}

// Should return 6
addAll(1, 2, 3);

// Should return 10
addAll(1, 2, 3, 4);

Fortunately, JavaScript does have an answer, though it is a little quirky. The answer is the arguments object.

Though it isn't exactly an array, the arguments object acts like an array that happens to contain every parameter passed to the function.

function myFunc () {
    console.log(arguments[0], arguments[1]);
}

// Outputs "param1" and "param2"
myFunc("param1", "param2");

Now that we know about arguments, it is easy to make an addition function that will operate on any number of parameters.

function addAll () {
    var sum = 0;

    for (var i = 0; i < arguments.length; i++) {
        sum = sum + arguments[i];
    }

    return sum;
}

// Returns 6
addAll(1, 2, 3);

// Returns 10
addAll(1, 2, 3, 4);

One problem to watch out for with arguments is that it isn't really an array. We can see this by running the following:

function myFunc () {
    console.log(Array.isArray(arguments));
}

// Will output 'false'
myFunc('param');

So it's not an array. Does that make a difference? Unfortunately, yes. It doesn't have any of the normal array methods like push, pop, slice,indexOf, or sort.

function sortArgs () {
    // This won't work!
    sorted = arguments.sort()

    return sorted;
}

This can easily bite you, especially if you pass the contents of arguments to another function which expects a real array.

The solution is surprisingly easy to use, but a little more difficult to understand.

function sortArgs () {
    // Convert arguments object into a real array
    var args = [].slice.call(arguments);

    // Now this will work!
    sorted = args.sort()

    return sorted;
}

What's going on here has several steps:

  1. We create an empty array.
  2. We use the array's slice method.
  3. We use the call method to tell slice that it should operate on arguments rather than on the empty array.

Invoking slice without specifying which index the slice should begin at will return an unsliced array. And that's how we end up with exactly what we want: a real array that contains every parameter that was passed to the function.

Published on


Default Parameters in JavaScript

Originally published in A Drip of JavaScript

Some languages — like Ruby, CoffeeScript, and upcoming versions of JavaScript — have the ability to declare default parameters when defining a function. It works like this:

function myFunc(param1, param2 = "second string") {
    console.log(param1, param2);
}

// Outputs: "first string" and "second string"
myFunc("first string");

// Outputs: "first string" and "second string version 2"
myFunc("first string", "second string version 2");

Unfortunately, this construct isn't available in current versions of JavaScript. So what can we do to achieve this behavior with our current set of tools?

The simplest solution looks like this:

function myFunc(param1, param2) {
    if (param2 === undefined) {
        param2 = "second string";
    }

    console.log(param1, param2);
}

// Outputs: "first string" and "second string version 2"
myFunc("first string", "second string version 2");

This relies on the fact that a parameter omitted at call time is always undefined. And it's a good solution if you have only one parameter to deal with. But what if you have several?

Well if you have more than a few parameters, you should probably be passing in an object parameter, as that has the advantage of explicitly naming everything. And if you're passing in an object parameter, it makes sense to declare your defaults the same way.

function myFunc(paramObject) {
    var defaultParams = {
        param1: "first string",
        param2: "second string",
        param3: "third string"
    };

    var finalParams = defaultParams;

    // We iterate over each property of the paramObject
    for (var key in paramObject) {
        // If the current property wasn't inherited, proceed
        if (paramObject.hasOwnProperty(key)) {
            // If the current property is defined,
            // add it to finalParams
            if (paramObject[key] !== undefined) {
                finalParams[key] = paramObject[key];
            }
        }
    }

    console.log(finalParams.param1,
                finalParams.param2,
                finalParams.param3);
}

That's a little unwieldy, so if you're using this pattern a lot, it makes sense to extract the iteration and filtering logic into its own function. Fortunately, the clever folks who write jQuery and Underscore have done just that with their respective extend methods.

Here's an updated version which uses Underscore's extend to achieve the same result.

function myFunc(paramObject) {
    var defaultParams = {
        param1: "first string",
        param2: "second string",
        param3: "third string"
    };

    var finalParams = _.extend(defaultParams, paramObject);

    console.log(finalParams.param1,
                finalParams.param2,
                finalParams.param3);
}

// Outputs:
// "My own string" and "second string" and "third string"
myFunc({param1: "My own string"});

And that's how you can get default parameters in current versions of JavaScript.

Published on


Books Every JavaScript Developer Should Own

For every programming language, there are a handful of books that are considered essential. Sometimes it is for their technical completeness, sometimes for expressing the "spirit" of the language, and sometimes for just writing a great introduction to the subject matter.

Here you'll find my attempt to distill a list of the essential books on JavaScript. They are not in any particular order.

Note: Even though I do provide links to the publishers/Amazon, I am not including a referral tag.

The Books

JavaScript: The Definitive Guide

Author: David Flanagan

The title really says it all. If there is something that you want to know about JavaScript, it is probably in this book. It is an extraordinarily complete reference. While I wouldn't necessarily suggest trying to read it from beginning to end, I do suggest having this tome on your bookshelf.

JavaScript: The Good Parts

Author: Douglas Crockford

In contrast to The Definitive Guide, Crockford's The Good Parts is relatively slim and highly prescriptive. While you may not agree with everything that Crockford says, this book is great for new and intermediate JavaScript developers to become familiar with common approaches and best practices in the community.

Effective JavaScript

Author: David Herman

Less rigid than Crockford, David Herman's Effective JavaScript is a collection of 68 specific solutions to common problems in JavaScript, and is probably the most immediately practical of the books listed here.

Async JavaScript

Author: Trevor Burnham

Unlike most of these books, Async JavaScript is about one very specific subject in the language, but it is a very important one: JavaScript's asynchronous nature. Over the course of the book Burnham covers such things as the JavaScript event loop, dealing with asynchronous events, promises, and web workers, and more.

Maintainable JavaScript

Author: Nicholas Zakas

Dealing with small JavaScript programs may be easy enough, but what about when your codebase starts to grow to a significant size? Luckily, Zakas is willing to share his experience from years as the tech lead for Yahoo!'s homepage. If your code is growing out of hand, this book will help you figure out how to get it into shape.

JavaScript Allongé

Author: Reginald Braithwaite

More playful than any of the other books listed here, JavaScript Allongé is an exploration of functions and functional programming in the context of JavaScript. This book is the one that has given me the most joy to read.

Conclusion

Of course, I haven't read every JavaScript book out there, so I may have missed one. If you'd like to suggest a book or two, why not discuss it on Hacker News?

Published on


Announcing the Drip of JavaScript Newsletter

A couple of weeks ago, I quietly began publishing an email newsletter about JavaScript. I have been sending it to a small group of friends and coworkers to see what they thought about the format, and to work any kinks out of the system. Feedback has been very positive, so today I'm happy to share it with you.

What is A Drip of JavaScript?

It is a weekly newsletter published every Tuesday, with tips to help developers "level up" in their JavaScript Skills.

Doesn't JavaScript Weekly do this already?

I love reading through JavaScript Weekly, but I'm trying something different. A Drip of JavaScript focuses on a single topic with a short and sweet article to help developers learn more about the language.

Do you have some examples of the topics you cover?

Sure do!

  1. Default Parameters in JavaScript
  2. Arbitrary Parameters with the "arguments" Object

How do I subscribe?

Go to the Subscription Form

Published on


6 Web Design Tips from Leonardo Da Vinci

Leonardo Da Vinci was one of the greatest artists of the Renaissance, leaving behind a legacy that continues to inspire artists, scientists and others. Here are six things we can learn from him about web design.


1. Be curious

One of the most remarkable things about Leonardo is his insatiable curiosity. Besides being a master painter, here are some of his other interests…

  • Botany
  • Music
  • Human and animal anatomy
  • Fluid dynamics (before there was a name for this branch of science)
  • Writing great poetry
  • Platonic philosophy
  • Designing remarkable inventions, including flying machines and a sort of pre-industrial tank

Many of these interests show themselves in his artistic work. Anatomy is obvious, but have you ever compared the ringlets of hair in his paintings to his drawings of water flow? Or thought of how rhythm, which is so essential to music and poetry, also shows up in painting and drawing?

The point is that being curious and learning about many things that are apparently unrelated to web design ultimately gives you more tools with which to design well.<!--more-->


2. Look beneath the surface

I've already mentioned Leonardo's interest in anatomy. His study of what lies beneath the surface gave him an understanding which enabled him to draw and paint his subjects remarkably well. Something similar applies in web design.

For the graphic designer, it might be studying the structure of HTML & CSS. For the front-end developer, it might be understanding the workings of a content management system. And for the back-end developer, it might be understanding the complexities of a relational database.


3. Build on the work of others

Despite his genius, most of Leonardo's achievements didn't spring fully formed from his mind like Athena from the head of Zeus. He was building on the works of others who were his contemporaries and predecessors. He studied under the Florentine master Verrocchio, from whom he learned the techniques and tradition of previous Renaissance art.

What does this mean for web design? Don't reinvent the wheel. Do your customers need to be able to manage their own site? Maybe all they really need is a little customization for Wordpress.

Building on the work of others is also the philosophy behind programming frameworks like Ruby on Rails, Django, and Symfony. Instead of writing everything from scratch, much of the work is already done for a standard web application.

And, of course, you can also use a CSS framework like Bootstrap to supply some good basic layout and typography settings before adding some customization.


4. Do quick studies

Before beginning work on a painting, Leonardo would often draw several studies of it, experimenting with different compositions and learning how the various aspects of the painting would interact with each other, all without having to start over from scratch if the first idea didn't turn out well.

This can be done in web design too. Have an idea for a layout? Sketch it on paper. Building a web app? Sketch out a use process. If it looks good, go for it. If not, try again.


5. Iterate

Leonardo didn't just iterate his studies. He also completely repainted (iterated) The Virgin of the Rocks.

But with web design we have it easier. If we want to redo our work and make it better, we don't have to start from scratch again. We can make continuous incremental improvements.


6. Be careful of experimental techniques

The final lesson we can learn from Leonardo is a warning. During his painting of the Last Supper, he employed an experimental technique for mixing his paint. While all seemed well at first, soon afterward cracks appeared in the painting, and since that time it has continued to deteriorate, leaving his masterpiece in ruins.

Web designers take note. While experimental technology is wonderful, be very careful about deploying it directly to a crucial system/site, otherwise it could leave you, like Leonardo, trying to mend the cracks.

Published on


Tool Builders

To ensure that things get automated, appoint one or more team members as tool builders to construct and deploy the tools that automate the project drudgery. Have them produce makefiles, shell scripts, shell scripts, editor templates, utility programs, and the like.

The Pragmatic Programmer

Published on


The Resale Value of Information

When a manager cannot tell the difference between information that is useful for predicting the outcome of a project, she thinks about the next best thing: The "resale value" of the information with people one step removed from the project, like her own manager. So she values things like pretty PowerPoints about the architecture higher than finished pieces of functionality.

What I've Learned from Failure, by Reginald Braithwaite

Published on


Podcasts for Hackers

If you're like me, and have a longish commute, it can sometimes be a challenge to fill your iPod/iPhone with the right mix of intellectually stimulating material and light listening. To help you out, here are the podcasts that have stood the test of time in my iTunes subscriptions.

Programming

Ruby Rogues

Hosted by Charles Max Wood, this is a roundtable podcast featuring some of the brightest Ruby developers around. The discussions tend to be deep dives into particular areas, like metaprogramming, the right way to do object-orientation, etc.

Javascript Jabber

This is a newer addition to my playlist, but it has already earned it's place. Another CMW podcast, this is to Javascript what Ruby Rogues is to Ruby.

The Javascript Show & The Ruby Show

20 minutes of the latest Javascript and Ruby news, with hilarious commentary from Jason Seifer and Peter Cooper.

Ruby5

5 minutes of the latest Ruby news twice a week. Great for when you just want a quick overview of what's happening.

Business/Startup

Mixergy

The granddaddy of all startup podcasts. Andrew Warner interviews dozens of startup founders to figure out exactly what it is that made them successful.

The Kalzumeus Podcast

There's only one episode out so far, but that was a great overview of how Patio11 got to where he is today. Keep an eye on this one.

Startups for the Rest of Us

This is very much a "how to" podcast, with lots of specifics on strategies and tactics for launching a software-based business.

Techzing

A rambling discussion podcast which covers pretty much everything, from conspiracy theory to weight loss, but the most consistent theme is web-based startups. And it is fascinating to listen as Justin and Jason work on building their own startup(s).

Build and Analyze

Another rambly one, this is hosted by Marco Arment of Instapaper fame, so it tends to cover the iOS/Mac/Android app ecosystem.

Founders Talk

This interview show by Adam Stacoviak invites founders to tell their stories.

Marketplace Money

Sometimes you just need to take a step back and think about your startup's place in the US or world economy. This NPR podcast will help you do just that.

General Enrichment

This Developer's Life

Does a podcast about the lives of developers sound boring to you. It did to me too. Fortunately, this podcast is not at all boring. In fact, it is just as good as the best of public radio, with experimentation in sound, storytelling, and theme. This will keep you coming back.

RadioLab

WNYC's RadioLab explores the intersection of science, philosophy, and life with a soundscape that you can recognize right away.

Podcastle & Escape Pod

Programmers tend to spend their days wrestling with literal-minded machines, so it's great to stretch our imagination in stories provided by these Fantasy and Science Fiction podcasts.

Writing Excuses

Need to stretch your imagination further? This 15 minute podcast ("Because you're in a hurry, and we're not that smart!") is a roundtable discussion with bestselling SF&F writers discussing the tools of their trade, and managing to make it entertaining at the same time.

Suggestions?

Obviously, a list like this will always be incomplete, but if you have suggestions, please post them in the comments on Hacker News, and I'll be happy to update with the more promising ones.

Published on