Monday, April 22, 2013

Javascript prototypes, prototype chains

Creating a single object

That's easy, just use an object literal:
// a vector
var v = {
    x: 0,
    y: 0
}

Factory functions

Say you want to create several objects of the same kind. Then a factory function will do the trick:

Prototypes

So what exactly is Vector2D.prototype?

Every function object has a special attribute called the function's prototype. The default value is an empty object, and can be read and set.

function F(){}
F.prototype

in chrome it will be printed as F {}, meaning that it's an empty object, and is attached to F.
Now, given that is a regular object, we can add some data to it:

F.prototype.x = 0
// F {x: 0}

or even replace it completely with another object

F.prototype = { x: 1 }

On the other hand, every javascript object has an internal property which is called the object's prototype, which is not to be confused with Function.prototype.

In chrome, there's a read only attribute called __proto__ that allows examining the object's prototype.

So, what's the relationship between Function.prototype and object.__proto__?

If you create an object via a factory function, then this relation will hold:

var ob = new F;
ob.__proto__ === F.prototype

that is, using new with a function F, constructs an object which has F.prototype as its own prototype (__proto__).

The interesting part about prototypes is that if you try to access an attribute from a object, as in:

ob.x

Javascript does the following

1. First tries to find 'x' in the object itself.
2. Then in the object's prototype: ob.__proto__
3. Then in the object's prototype prototype: ob.__proto__.__proto__
4. etc
5. Until it reaches the topmost prototype, which is an empty object.

This looks very similar to class inheritance in a language with classes, right?

So, how can we setup an prototype chain as in #3?
Returning to our vector example, the current situation is this:

if
var v = new Vector2D;
then
v.__proto__ === Vector2D.prototype;

lets say we want to have Vector2D inherit from something more general, like an n-dimensional Vector:
in other words, we want that v.__proto__.__proto__ === Vector.prototype

In order to answer this, lets pose the question this way: If I have an object x, how can I get another object y which has x as its prototype?

y.__proto__ === x

There's an ECMAScript 5 function for doing this: Object.create():
var y = Object.create(x);
y.__proto__ === x;
And this is all we need to setup a prototype chain. Of course we need to do this *before* start adding methods to Vector2D.prototype, otherwise they'll be overwritten:
this have the interesting effect that Javascript knows about v2's constructors:
v2 instanceof Vector2D === true;
v2 instanceof Vector === true;

Tuesday, March 12, 2013

Promises I

This is the first post in a series about jQuery deferred objects, and async patterns in general.

A  deferred object is an object with an initial 'pending' state, and two possible final states: 'resolved' or 'rejected'.

Since jQuery version 1.5 the $.ajax() implements the Promise interface , so we'll focus on ajax connections.

Fetch some json data from a webservice

The most basic example of using a promise; just get some data from the server and do something with it.

  • Line 1 initiates the ajax connection to the server. The result from $.getJSON() is a promise, which is a read-only view of a deferred object.
  • Lines 11 & 12 install a couple of success handlers
Of course in this case the callbacks could've been added in the same line as the ajax call, as in

$.getJSON(url).done(logData).done(displayData);

but the point is that the promise is a regular object which you can save, use as arguments of functions, etc.

One important consequence of this is that you can split the ajax initiation event from the use of the ajax result in your code

This pattern allows you to structure better your code; because the client object is completely agnostic about the use of the data.

Sunday, February 24, 2013

On modern Javascript applications

I use to consider myself more a backend python type developer, but the last year I was writing javascript / java most of the time. So I guess I'm a front-end guy now.

We've been building a medium-large Backbone site, with a java backend. Because we all have MVC backgrounds (grails, django, asp.net mvc, etc), and zero experience doing Java2EE stuff, we choose Play (1.2 at the time) as our backend framework.

The site is in production now, running smoothly. It's not perfect but is improving all the time. I've learnt a lot, specially front-end wise. Here are some of my impressions.

  • RequireJS. It's a must have for any medium to large size project. It allows you to break down your javascript application in modules, and declare dependencies inside each module. Specially with a code-intensive framework like backbone, managing all your files quickly becomes a nightmare unless you use some type of dependency management.
  • Backbone. It's small, minimalistic, and very good at what it does. It has components for managing routes, events, models with backend synchronization, easy prototypal inheritance, and that's it. Paired with something like RequireJS allows you to have a very modularized application, with reusable components (if you have good coding practices).

    The issue with backbone is that being so minimalistic, you need to build a LOT of infrastructure, so you need to know a lot of javascript techniques for modularizing your code, writing reusable code, etc. It's unlikely you get it right the first time.

    One of the things it lacks with rotundity is some mechanism for data-binding between your models and the DOM.

    And believe me, you want data-binding.

    So, at this point you have several options:
    1. Manually bind some DOM elements with your model and viceversa (using backbone events).
      This is very labor-intensive, boring, and not cool at all. Small changes in the UI logic require non-trivial amount of work.
    2. Use one of the available plugins, like Backbone.ModelBinder, or RivetsJS. Oh, you will also need Backbone.DeepModel, which is rather buggy and handle a relative small set of cases. RivetsJS is a little more powerful than ModelBinder, but still very very minimalistic compared to KnockoutJS or AngularJS.
      This is an improvement over the manual approach, but still requires tremendous amount of work for everything beyond the minimum.
    3. Use KnockoutJS on top of your backbone views. The problem with this approach is that KO's models are different than BB's models. So you need a way to transform between the two models. That can be done by hand, or via KnockbackJS.
      If you go this way, be prepared to have a steep learning curve, and hard time finding guys with all the skill set needed to be productive quickly in your project. Of course they will learn, eventually.
      And of course KO is very idiosyncratic and some people argue that it allows you to do some dirty stuff.
  • AngularJS. The alternative to Backbone / Spine / Knockout / whatever is to use Angular.
    It has almost all components needed for building a full javascript application (the missing part is RequireJS, but it's no so terrible). It has a completely different way of doing things, in particular because it goes to great lengths to make you difficult to mix your view logic with DOM manipulation. I won't describe Angular here, but suffice to say I'll be writing most of my javascript apps with Angular in the near future. Key features of AngularJS are:
    • You can build stuff FAST.
    • Forces you to have modularized components
    • Which makes controller logic much more easy to test
    • Allows you to create reusable widgets, Services, Factories
    • POJOs everywhere. No need to learn a new api for model manipulation, just plain JS.
    • Boilerplate code reduced dramatically
    • Makes your dog happy, helps fight global warming, etc etc etc.
  • Yeoman. It is described as "a workflow; a collection of tools and best practices working in harmony to make developing for the web even better". It's comprised of three components:
    • Yo. Scaffolding and Grunt task management
    • Bower. Client side package / dependency management
    • Grunt. Used to build / test / preview your project. You can make your own grunt task easily.
  • Now, the question is this: Why on earth you're not using Yeoman???? Really, I guaranty you'll become a better person / happier / healthier if you use Yeoman. 

Sunday, October 28, 2012

Challenge: Create a diagram depicting water from a garden hose, following a parabolic trajectory (for a math text book).

At first I tried to do it with inkscape; using the "Tiled clones" feature. That proved impossible: I could create the water drops, but not make them follow a parable.

So I ended up doing it in Mathematica. Here's the code:
And the results:

The idea is to start with nearly identical "streams" but introduce a small vertical perturbations which depends on the x coordinate (so it grows to the right). 

Saturday, October 13, 2012

Java 1.6 vs Scala

So the other day I found this code:
  Which needs the library guava from google. This is very interesting, because for one, I didn't know you could do that I java. The other reason is that we can make fun of java 1.6 by comparing it to the scala version:
 

Sunday, July 15, 2012

async map

Recently I've been amazed by the flexibility gained when using jquery's deferred object.  So I'm using it whenever I have the chance :)

As an example, here is an asynchronous version of the good ol' map.

Several improvements are left as exercise to the reader: accept non-deferred objects; sort the final response so that it matches the input's order, etc.

Thursday, September 8, 2011

List of Technologies used in my current project

Current:
  • Django (of course)
  • South
  • Virtualenv
  • Fabric
  • Compass
  • CoffeScript (a little)
  • Celery
Short term:
  • Tornado
  • Spine / Backbone / Batman.js / knockout (TBD)