JavaScript Mixins

Mixins (a.k.a. modules) are a convenient and useful way to package up pieces of behavior.

  /**
  * Bindable module
  * @name Bindable
  * @constructor
  */
  function Bindable() {

    var eventCallbacks = {};

    return {
      /**
      * The bind method adds a function as an event listener.
      *
      * @name bind
      * @methodOf Bindable#
      *
      * @param {String} event The event to listen to.
      * @param {Function} callback The function to be called when the specified event
      * is triggered.
      */
      bind: function(event, callback) {
        eventCallbacks[event] = eventCallbacks[event] || [];

        eventCallbacks[event].push(callback);
      },
      /**
      * The trigger method calls all listeners attached to the specified event.
      *
      * @name trigger
      * @methodOf Bindable#
      *
      * @param {String} event The event to trigger.
      */
      trigger: function(event) {
        var callbacks = eventCallbacks[event];

        if(callbacks && callbacks.length) {
          var self = this;
          callbacks.each(function(callback) {
            callback(self);
          });
        }
      },
    };
  }

On the face of it this Module only constructs a simple object with two methods bind and trigger. A statically typed language may make use of delegation to forward method calls to a Bindable object created for each class instance, but in dynamic languages we can literally mix this object into the object that wants to make use of it’s capabilities.

function Guy(I) {
  I = I || {};

  $.reverseMerge(I, {
    name: "Sancho"
  });

  var self = {
    sayHi: function() {
      alert("Hi, my name is " + I.name);
      // Make use of the method provided by the Bindable class
      self.trigger("spoke");
    }
  };

  // Mixing it in, just smash the methods of the newly created Bindable onto this object
  $.extend(self, Bindable());

  return self;
}

var guy = Guy();

guy.bind("spoke", function() {
  console.log("This guy spoke");
});

guy.sayHi(); // Alerts and logs to console

Some modules may require a method to be provided by the host. A classic example is an Enumerable module which can provide many additional iterators if given a standard each iterator.

function Enumerable() {
  return {
    partition: function(iterator, context) {
      var trueCollection = [];
      var falseCollection = [];

      this.each(function(element) {
        if(iterator.call(context, element)) {
          trueCollection.push(element);
        } else {
          falseCollection.push(element);
        }
      });

      return [trueCollection, falseCollection];
    },

    select: function(iterator, context) {
      return this.partition(iterator, context)[0];
    },

    reject: function(iterator, context) {
      return this.partition(iterator, context)[1];
    },

    shuffle: function() {
      var shuffledArray = [];

      this.each(function(element) {
        shuffledArray.splice(rand(shuffledArray.length + 1), 0, element);
      });

      return shuffledArray;
    }
  }
}

This Enumerable mixin provides partition, shuffle, select and reject methods. It relies on the host providing the each iterator, and makes use of it to provide partition and shuffle. The select and reject methods in turn make use of the partition method.

// Mixing enumerable into Array.prototype

//Alias forEach as each to provide the method by a name Enumerable knows
Array.prototype.each = Array.prototype.forEach;

// Mix it in
$.extend(Array.prototype, Enumerable());

[1, 2, 3, 4, 5, 6, 7, 8].select(function(n) {return n % 2 == 0}); // => [2, 4, 6, 8]

This covers the classic uses of mixins, though there are some extra cool things that you can do when using instance variables. For now I’ll leave that as an exercise for the reader but later I’ll spell it all out in a follow up post and in my upcoming book Daniel X. Moore’s {SUPER: SYSTEM}.

Object#reverseMerge – Useful JavaScript Game Extensions #19

Object#reverseMerge a method that complements Object#merge nicely. In regular merge all the properties of the source are copied onto the destination, but in reverseMerge the properties are only copied over if the destination doesn’t already have the property.

Object.prototype.reverseMerge = function(source) {
  for(var key in source) {
    if(source.hasOwnProperty(key) && !(key in this)) {
      this[key] = source[key];
    }
  }

  return this;
};

This allows us to easily have a list of default properties in an object and add them to the destination object only if they aren’t already present.

var iceCreamDefaults = {
  flavor: "vanilla",
  price: 2,
  size: 4
};


var chocolate = {
  flavor: "chocolate"
}.reverseMerge(iceCreamDefaults);

chocolate.price; // 2
chocolate.size; // 4

In the example we have an object containing ice cream default values. These values are merged into the chocolate object we create, but only if they don’t already exist within that object.

Extending Object.prototype is fun and rewarding, but it’s not without it’s pitfalls. For example jQuery is not yet 100% compatible with code that extends Object.prototype, though it has plans to be in the future. In addition, the presence of prototype properties in all your objects is one extra edge case to consider when using for in iteration and the in operator. The primary question is whether the benefit added by Object.prototype extensions exceeds the risk of the extra complexity, and in the end it comes down to what the biggest pain points are in the code in your own specific circumstances. Like most programming practices that involve trade-offs their correct usage depends strongly on the context where they are used.

Be sure to subscribe to get all the latest updates!

Bonus section, an alternate implementation using Object#each:

Object.prototype.reverseMerge = function(source) {
  source.each(function(key, value) {
    if(!(key in this)) {
      this[key] = value;
    }
  }, this); // context argument to ensure that `this` references correctly

  return this;
};

Again, be sure to subscribe so you don’t miss any of this amazing series!

Object#each: Useful JavaScript Game Extension #18

Part 18 of 256

Previously we discussed extending Object.prototype and adding a merge method. One of the big issues with messing with Object.prototype was that there was no standard and easy way to iterate over the non-prototype properties of an object. Remember that each method that I said was from the future? Today is that future.

/**
* Iterate over each property of this object, excluding prototype properties.
* It does this by excluding properties that aren't its own with `hasOwnProperty`
*
* @param {Function} iterator Receives two arguments for each property, the key and the value.
* @param {Object} [context] Optionally specifies what context the iterator will be called with.
*/
Object.prototype.each = function(iterator, context) {
  for(var key in this) {
    if(this.hasOwnProperty(key)) {
      iterator.call(context, key, this[key]);
    }
  }

  return this;
}
var candyPrices = {
  taffy: 0.95,
  rock: 1.25,
  lollipop: 0.50,
  licorice: 0.25
};

candyPrices.each(function(name, price) {
  alert("The price of " + name + " is $" + price);
});

This will allow us to iterate without having to write our own brittle for in iterators, and will be much more robust from breakage. If you are using for in you’ll need to decide whether or not prototype methods should be included. Here the decision already made, hopefully in a sane and generally robust manner.

Don’t worry about Array#each, it’s own prototype method will override this one so that array iteration is unaffected by this.

There are a few more useful Object.prototype extensions coming up, so stay tuned for the rest of the series.

Object#merge – Useful JavaScript Game Extensions 17

Yesterday I wrote about Object.extend, a useful method for building objects out of smaller pieces. Commenter Kieran posted a reply saying that it might be better as an Object#merge method. My initial reaction was an aversion to extending Object.prototype, so I went on a journey to figure out why I believed that.

Back in 2003, prototype.js extended Object.prototype with extra methods. There was a big outcry, “You’re breaking my [badly written] code with your library!!1”. Apparently it was common practice to use objects as hash tables and use for in iteration on them without using a check like hasOwnProperty. And jQuery didn’t exist then, and unit testing for JavaScript didn’t exist, or was never practiced, and there where thousands of badly written libraries that you could copy-paste into your app and watch it break because prototype.js extended Object.prototype.

So naturally there was a massive outcry Object.prototype is verboten, and continuing through to December 2009, Prototyping Object in Javascript breaks jQuery?. Though in the latter one the breakage was acknowledged as a bug in jQuery, the general consensus was that it was “bad practice” to extend Object.prototype, citing again for in loops primarily.

So the cautious thing to do is to never extend Object.prototype. This is most likely correct if you are distributing a library to millions of people who need to use it in diverse and hostile environments, aka the web. Are you delivering a library to millions of people who use it in diverse and hostile environments? No? Cool, continue reading then.

For my own code, that I run on my own site, I have quite a lot of control over it. I can choose to use external libraries or not, and patch them if they are using for in loops in some weird way. So I’m going to give it a shot and try extending Object.prototype.

Object.prototype.merge = function(source) {
  for(var key in source) {
    if(source.hasOwnProperty(key)) {
      this[key] = source[key];
    }
  }

  return this;
}
var BLT = {
  bacon: true,
  lettuce: true,
  tomato: true
};

var Reuben = {
  cornedBeef: true,
  russianDressing: true,
  saurkraut: true,
  swissCheese: true
};

var sandwich = {};

sandwich.merge(BLT);
sandwich.merge(Reuben);
sandwich.merge({
  name: "custom",
  price: 6
});

// each...? Never heard of it. (Don't worry, it's from the future).
sandwich.each(function(key, value) {
  console.log(key + " is " + value);
});

// bacon is true
// lettuce is true
// tomato is true
// cornedBeef is true
// russianDressing is true
// sauerkraut is true
// swissCheese is true
// name is custom
// price is 6

That doesn’t seem so bad… though if my past experience with JavaScript has taught me anything it’s that everything is likely to come back and bite me in the ass.

Extending Object.prototype provides a not-insignificant gain of clarity in the code. It also provides a potentially dangerous pitfall that can lead to trouble if used in some situations. I always think it’s a good practice to exchange real problems for hypothetical ones, so this is a trade-off I’m likely to make. I haven’t yet extended Object.prototype in a major JavaScript project yet, I guess I’m still a little gun-shy from having been burned so often by JS in the past. That said, I will definitely be trying it out and seeing for myself if the dangers are real or imagined.

JavaScript Game Extensions: Object.extend

Part 16

Object.extend is an incredibly useful method in JavaScript. It can be used to dynamically augment object capabilities, create composite objects, and to provide a mechanism of inheritance.

Here is the method in it’s simplest form (from prototype.js):

Object.extend = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }

  return destination;
}

The method takes two arguments, a destination and a source. It then copies over each property from the source to the destination and returns the destination. This allows you to do things like:

var BLT = {
  bacon: true,
  lettuce: true,
  tomato: true
};

var Reuben = {
  cornedBeef: true,
  russianDressing: true,
  saurkraut: true,
  swissCheese: true
};

var sandwich = {};

Object.extend(sandwich, BLT);
Object.extend(sandwich, Reuben);
Object.extend(sandwich, {
  name: "custom",
  price: 6
});

Ok, so that’s pretty cool if we’re talking about sandwiches, but how often does that happen? Well if you imagine the sandwiches are classes and the toppings are methods then you’ve got a pretty modular system for constructing objects.

The extend method can be modified to add more smarts and power to it, but at it’s heart it is simply copying properties from one object onto another.

Hmm, all that talk about sandwiches has made me hungry.

Stay tuned for the rest of the series as well as my upcoming book {SUPER: SYSTEM} where I will go into much more detail.

Useful JavaScript Game Extensions: Number#round

Part 13

Here’s another small one, in the same vein as yesterday’s. When you can take for granted that numbers behave as objects, it really cleans up unnecessary references to static Math methods and extra helper methods.

/**
 * @returns The number rounded to the nearest integer.
 *
 * (4.5).round(); // => 5
 * (4.4).round(); // => 4
 */
Number.prototype.round = function() {
  return Math.round(this);
};

Take a look back at the original useful JavaScript game extension Number#Clamp. Though global helper functions have the same number of semantic elements, I find that it’s easier to break down in my head if they are attached to objects. Also, the order of the parameters may be more obvious if you reduce it from 3 to 2.

Useful JavaScript Game Extensions: Number#sign and Number#abs

Part 11 and 12

In an object oriented perspective it can be useful to think of numbers as objects. Why have to deal with “everything is an object, except numbers, those are different and require special methods”, when you can have a more consistent programing environment where numbers are objects too, and have the same interfaces and methods you’d expect.

JavaScript’s prototype based inheritance is perfect for extending the behavior various types of objects, and fortunately for us, unlike in Java, in JavaScript numbers really are objects. Though unfortunately for us, as is usual in JavaScript, the API is seriously lacking.

Getting the sign of a number can often be useful in games. For example, I wanted to have camera tracking where the camera would look ahead by the square of the velocity of the object. But if the object were moving in the negative direction the squaring would obliterate the sign. Number#sign to the rescue!

/**
 * @returns The sign of this number, 0 if the number is 0.
 */
Number.prototype.sign = function() {
  if(this > 0) {
    return 1;
  } else if (this < 0) {
    return -1;
  } else {
    return 0;
  }
}

// Example, using the sign to maintain direction when squaring
var weightedX = dinoPosition.x + (1.25 * dinoVelocity.x * dinoVelocity.x * dinoVelocity.x.sign());

Another useful number method is abs. Why do you need some external object to get the absolute value of a number? Shouldn’t a number know it’s own absolute value? Now they can:

/**
 * @returns The absolute value of the number.
 */
Number.prototype.abs = function() {
  return Math.abs(this);
};

I’m not always against the prototype feature of JavaScript, just against using prototype based inheritance to simulate class and module based inheritance. Stick around towards the end of the series to see some great examples.

See you next time!

Quest for Meaning a game made in two days for Mini-LD #21

Here it is, my entry for the mini-Ludum Dare competition. The competition theme is “biggest fear”, and one of my biggest fears is a meaningless life. Not only that, but a meaningless eternity. Pictures for Sad Children has a very similar theme at times and it helped inspire parts of this game (though I couldn’t find a good way to work in “monster most vulnerable when heaving with sobs”).

This was my first 2 day competition and I’ve learned some things. First, two days is a long time. Second, having real tools would make me very, very happy. Third, I thought that doing all the art and all the programming for a game would be hard, but it seems to use different parts of the brain, so when working on art the programming part of my brain is relaxing and vice versa.

This was the first moderately legit game that I’ve done all my own art on (title screen and chest graphics contributed by Lana). Also, my first game with a 4 color grayscale pallet. And additionally, my first major undertaking on the Pixie platform.

Working with the Pixie platform had some serious trade-offs. JavaScript is a surprisingly productive language with it’s functional and dynamic nature, but it has a harsh and brutal syntax. The platform libraries helped a lot to smooth some things out, and as they become more complete it will get better and better. I have high hopes for CoffeeScript, now that it is getting close to 1.0 I’m going to try using it on all my new projects and hopefully never go back. Another advantage was the tight art and code integration. It was trivial to create an image and have it appear in the game seconds later. The biggest drawback of Pixie right now is that the code “editor” is pretty much just a text area. There are no tabs, no integrated source navigation, no auto-save, no version control, and all kinds of other terrible issues. Also, there is no real tile editor, though Noel Berry pioneered the way by using the pixel editor as a tile editor before, and the surprising thing is that it’s actually not too bad.

Using Pixie to make art is awesome, but the game “platform” is not fleshed out enough for me to recommend making an entire game in it to everyone yet.

A special thanks to everyone who helped playtest and discuss various elements of the game throughout it’s stages: Boltz, McGrue, DavMo, Lan, MW… props.

So check out the game and let me know what you think. By making heavy use of Pixie, especially in time limited competitions, I hope to really iron out the core usage scenarios and make it amazing.

The future is bright and full of meaning.

Useful JavaScript Game Extensions: Array#first and Array#last

Part 9 and 10 of 256: Array#first and Array#last

The first and last methods of array objects provide a nice semantic wrapper for the concepts. They aren’t really a big time saver, though it is probably very slightly easier to type first than [0]. It is also fairly uncommon to need these methods with much regularity, but when you do need them it’s nice to have them.

/**
 * Returns the first element of the array, undefined if the array is empty.
 *
 * @returns The first element, or undefined if the array is empty.
 * @type Object
 */
Array.prototype.first = function() {
  return this[0];
};

/**
 * Returns the last element of the array, undefined if the array is empty.
 *
 * @returns The last element, or undefined if the array is empty.
 * @type Object
 */
Array.prototype.last = function() {
  return this[this.length - 1];
};

JavaScript Instance Variables Do Exist

In JavaScript you can use a closure to create private member variables. Many, many, many, people refer to these private member variables as instance variables. They are wrong.

An instance variable should be accessible to any methods of the class, including methods from superclasses and modules. So, I suppose private member variables provided via a closure are indeed “instance variables” if you live in a world without any superclasses or modules. In fact that is the world that most JavaScript lives in, a dark and terrifying world… but let’s not speak of the darkness, instead let’s turn towards the light…

Instance Variable Pattern

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Notice how it doesn’t matter which class declares a method, the instance variables are accessible to the instance of the class. I know what you’re thinking, I can see you there with your jaw gaping, slacking in the wind with disbelief. You’re saying “.. buh … buh .. Object.extend? Object.reverseMerge?? Those aren’t even real JavaScript!!” And you’re right. If I had a dime for every time an important method wasn’t part of “real JavaScript” I’d easily be a multi-thousand-aire.

If you’ve used jQuery, prototype, or probably any other decent JavaScript framework, or just a decent amount of JavaScript, you should be familiar with Object.extend, $.extend, _.extend. Extend copies properties from one or more objects to a destination object, overriding them if they share the same key.

reverseMerge is less common, but equally useful. It does the same as extend, but does not override keys that are already present in the destination. This makes it perfect for adding defaults without crushing existing values.

The I variable is a convention to let you know that you are accessing instance variables, similar to Ruby’s @ prefix. It is very important to pass the reference to this variable to the superclass, otherwise you will not actually have a shared instance variable space. Any method can add a new instance variable by something like I.foo = "bar"; The dynamic nature of JavaScript makes this legit. Though in practice it is polite to declare any defaults for instance variables your class or module uses in the reverseMerge so someone can just glance there to see what a class or module declares and depends on.

The line I = I || {}; is to allow you to instantiate a class without passing any configuration options and to just accept the default values. “Wait, WHAT? Configuration options? I thought this was an article about instance variables!!” That’s right, configuration options. Now that we have instance variables it would be silly to have two different ways of doing a very similar type of thing. It is a common jQuery convention to do $('.someClass').somePlugin(someOptions); Those options override the defaults if present, how eerily similar. The classic jQuery plugin convention however creates a new empty object and merges in the defaults as well as the overrides. Again this is fine in a world without inheritance, but once inheritance becomes involved you’ll be glad you have true instance variables.

Now, back to the issue of private variables. Private variables are very useful and I use them regularly. A good programmer makes use of all privacy levels: public, private, and protected/instance. Knowing what level of access to make a component is important. If everything is public then your API becomes a morass of incoherence. If everything is private then modifying and configuring behavior can become arduous. The right blend leaves your code elegant, coherent, configurable, and flexible. Remember, true instance variables do exist in JavaScript and they can be a valuable addition to any programmer’s toolkit!