Wednesday, May 1, 2013

Logic in templates

Template engines have seen a recent rise in use with the popularization of the MV* model of programming. It's easy to see why, we are no longer writing websites where content is key, but creating dynamic applications where user interaction decides what is on screen. Because of this we don't want to download html from the server every time, instead we want to take our data and put it in a template that we can reuse for the layout. It's an obvious choice and one that works well. However we've started to run in to a bit of a problem, but first a recap on some HTML history:

Event Handlers in HTML

Not so long ago we were writing things like this:

<a href='#' onClick='window.open("http://rhysbrettbowen.com");'>open site</a>

okay, not a good example but that's not the point. The point was that we were littering our HTML with code that only run on an interaction with the element. The issue wasn't the element interaction, it was where we put the actual logic. The issue is that putting actual implementation logic in the HTML gave us a whole other place to hunt for bugs and find where logic was, plus it looked ugly. Sometimes the code you wanted to write had to be more than a few lines long, and things really got bad. It also meant that any change to the implementation logic would have to be changed in the HTML, and changing the HTML may change the behaviour of the page so it meant less people could alter it.

Event Handlers in Scripts

So then we put our event handlers in the scripts. This was great and solved all sorts of problems. It meant that we could get a handle to an element and attach functionality there. This meant we could also change the functionality based on different circumstances. This worked great, while we knew what HTML was on the page. Then we started to get clever and made our pages dynamic.

Event Handlers in Templates


So we started using templates which could have data passed in to them. This meant we had the power to inject data directly in to the DOM before adding it to the page. We also put in functionality in things like data attributes that would declare what functionality an element should have, and all this is a good thing. (Also please note the difference in declaring the functionality, we now declare something on elements but the actual implementation lives in libraries like Knockout or Angular).

Back to the issue at hand

The problem though is that with the ease of using templates we forgot about the bad old days and reintroduced logic in to the template. By logic I mean things like "IF" statements. The issue with IF statements is that they increase code complexity, and they're doing it in the template which is a place that we would like people like designers and other non-professional coders to write. Every time you nest and IF statement you increase the factor of code paths through your code by 2. So if you have 3 IF statements then you suddenly have 2 ^ 3, or 8 different paths your code can take. Because it's logic you should then be writing 8 different tests for your template to get 100% coverage. Do you really want to do that?

So how do we fix it?

The fix is usually quite easy. In most cases you can compute a value and pass it in to the template. This works for things like adding on a class depending on a value. You can use things like rivetsjs to declare your intent in the data attributes in a manner easy enough for a non-professional coder altering the template to understand and use (DSLs like this are great for a while team to learn so they can collaborate together).

In pure OOP there are no IF statements - there is even a website about it. Basically instead of an if statement with two paths you have two different objects. These object share a function name and dependent on which object you call a that function will run. In the case of MV* we've already got objects that come out as DOM, and that is our views (or controls dependent on how you look at it). So all you need to do is write your top view and pass in to it the subview that should be shown in that spot, now dependent on which subview you pass in you will have different things appear in the dom (as they themselves have different templates). The disadvantage to this is no you have a view hierarchy, but if you already have a view manager this should be easy to use. The advantages though are great, you've removed complexity from the templates and what's more you've also broken out the templates in to more logical pieces. Now you can work on those subview templates individually (and I bet they'll increase in complexity over time so you'll be saving yourself a headache).

The other great thing is now there is no logic in the template you shouldn't need to run it any time there is a change in the data. A problem is an if statement may not put some elements in the page, that you'll want to show on the data change, so you would have to re-run the entire template. If you've split out in to a smaller view, you only have to replace the view and the rest of the template can remain untouched. That's a big win not having to re-render DOM and reset all event handlers. Also because you no longer have to re-render the entire DOM you can now use bindings between elements, as those elements won't change.

So just say no to logic in templates.

Wednesday, April 17, 2013

a Library or a Framework?

I've heard this question asked many times: "is it a framework or a library?" and even "what is the difference?". It's quite tricky to differentiate between the two and often the difference doesn't really matter. I've heard a few concerns about using frameworks because they lock you in to their style and way of programming, but this should be seen as a good thing, not a bad one. I'll go over that later, but first - just what is the difference?

The way I like to think of it is that a framework is something you build on (decides structure) and a library is something you build with (has little influence on structure).. It's a simple distinction and one which can get a bit gray or fuzzy. The real reason is that people try to define these projects as one or the other, but what defines them as a library or a framework is how we use them.

The other issue is that we can split frameworks and libraries in to categories. Frameworks tend to span multiple categories and so they are more likely to have an impact on what other tools you can use. Here is a list of categories that libraries/frameworks work on (though it may not be exhaustive):


  • Application Layer (e.g. initialization)
  • Communication (e.g. mediator)
  • Storage (e.g. localstorage)
  • Events
  • DOM
  • UI (widgets)
  • Timing
  • Data (models)
  • Inheritance
  • Animation
and so on. It might be easier to have a look at a few libraries/frameworks and see how they fit in:

jQuery

library. Although using it can litter your code with dollar signs and many people start with it, you can just as easily pull out jQuery, put in vanilla javascript (although it will be longer) and there shouldn't be much worry.

Ember


framework. Try pulling out any ember related code and see how much of an application you have left.

AngularJS


framework. If you have a look on their website they even call it an MVW framework.

Backbone

library or framework. It depends on how you use it. Backbone can be easily added to projects and if you're just using the models then I'd call it a library because they can be easily replaced. However Backbone does also give you an events system and views and give you a way to inherit from from it's view. If you're using all this then it's become a framework because you're using these tools to build your application and they're not so easily replaced (by easily replaced I mean you can go to the backbone specific code in your project and pretty much just replace code at that point).

Closure

library & framework. Closure is a bit different. It has a library full of utility methods that are easily replaced so that part is a library. However it has dependency management and inheritance goog.ui.component which will defined how you structure your application so it's both.

Knockout

library. It gives you data binding which may influence how you structure your application but in no way controls it.

So what do you use? is it a library or a framework? 

Wednesday, March 6, 2013

What I don't like about Backbone

Yes, this will probably start a flame war of sorts, and no we don't all have to agree on this subject.

I've recently moved cities and jobs (which is why I haven't had any updates for a while) and I'm now at a place called Dataminr. Dataminr decided to go with Backbone and use Backbone.LayoutManager to control their views. So now I'm working on Backbone until the next big release when we're going to talk about redoing the architecture.

So what have I been up to? Well for the first few days I was banging my head just wishing that Backbone or Backbone.LayoutManager had certain functionality that I was used to. Then I decided to add the functionality myself, and as I did so I ran in to more problems, problems that are baked in to the core of the two libraries. So my gripes come in two different sets:

1. Things I wish they did.
2. Things I wish they didn't do.

so I'll go through them and then some other things I was thinking when starting or discovered, and finally what I did.

Things I wish They Did

I don't like the separation of model and collection. What if I want a collection of collections? I wish Collections was extended from model.

Why isn't Sync an object? It's just a function. Why is everything else an object but only Sync is a function? It'd be great to have it as an object with it's own events and methods so you can just override parts of it instead of having to write the entire thing from scratch if there is just one line you don't want there. We could extend it with something like this:

Backbone.SuperSync = {
getSync: function(options) {
return _.bind(this.sync, this);
},
sync: function(method, model, options) {
this[method.toLowerCase().substring(0,4)](model, options);
},
post: function(model, options) {},
put: function(model, options) {},
get: function(model, options) {},
dele: function(model, options) {}
}

Some way to have a single model across multiple collections would be nice.

This is mostly pointed at LayoutManager as Backbone takes no responsibility for how a view should function:

A listview that can handle itself. it's that simple. It's 2013 already, I just want to have a listview with a collection and tell it what the child views should be. I don't want to listen to events and update it, I want that done for me. Showing a list should be bread and butter.

Pass along events from the collection on to the view. This kind of goes with the previous point, when a child is added to the collection, a view should be added (and in the proper order) and then an add event should fire.

Why are views not kept in the same order as the collection? What happens if I want to change the sort order? Do I really have to throw out all my perfectly good views and start again?

Also I had a bit of trouble with the events passing up from a subview, it seemed that to pass them along I needed to trigger it on the element instead of the object - maybe it's just me.

Things I wish they didn't do

Models should not have a reference to their collection. They just shouldn't. If I want a model in more than one collection, which collection is going to be put on the model and why? Why do I need a reference? I'd argue it just promotes bad coding practices.

The render function, as the be all and end all of the view. I really wish there was a bit more flesh to the Views rather than just run a single function as the end result. It promotes the render function as a dumping ground for all the logic of the view.

That extend method. The code I'm working on has the extend method used to setup inheritance chains throughout the code so I have to go hunting to see how things are implemented.

why does LayoutManager use an append method on the child and not one from the list? How is the child supposed to know how to place itself in the list?

Other things:

Turns out I didn't miss binding data to elements too much, but this is mostly because the data comes from the server and acts as alerts rather than being data models that the user can change. Once a model comes in it's probably not going to change.

There are some things I liked about Backbone though. I do like how the add model will try and createModels using the _prepareModel method which is great to override and put in some custom logic.

What I did about it

okay, so the first thing I didn't like was that extend method. If it's going to be that flexible then may as well make it REALLY flexible. I wrote a method that could use functional mixins to mixin functionality on to Backbone constructors. Now with that I could mixin any type of functionality I needed. The first thing I wrote mixins that made views selectable, expandable, focusable etc. Then came the autolist functionality and a model registry.  Now I'm replacing LayoutManager with a new manager that is based off of goog.ui.component. It's a little different to how you're taught to use Backbone - you only render a view ONCE, then you just update it on events, though you can always force it to recreate the DOM if you're feeling lazy. This also solves a lot of complexity in LayoutManager that has to handle things being asynchronous, to give you an idea it has the same functionality and is about half the size. I'm hoping that I can release the code soon as I'm expecting that the mixins system will be the extremely handy for those creating views, to give you an example this is what it looks like:

var EventList = Backbone.View.extend({
  template: listTemplate,
  itemView: EventItem
}).mixin([
  Mixin.view.autolist,
  Mixin.view.keyboardNavigatableList,
  Mixin.view.keepScroll
], {
  scrollEl: '.scroll-container'
});

for a look at what the mixins look like, it's something like this:

Mixin.view.keyboardNavigatableList = function(options) {

        this.mixin([
            Mixin.view.handleKeyboard,
            Mixin.view.singleSelectChild
        ], options);


        this.after('onKeyup', function(event) {
            if(event.keyCode == $.ui.keyCode.DOWN) {
                this.selectPreviousChild();
            } else if(event.keyCode == $.ui.keyCode.UP) {
                this.selectNextChild();
            }
        });

    };

and that's it! give it a collection and it'll keep itself updated, you can navigate the children with your keyboard (up and down) and it will keep the scroll on the child when new elements are added (we add them at the top).

I'm sure there are more points I'm forgetting and some of the points I made are fixed with other plugins and some of these are more specific to using LayoutManager. For now I've got to get back to working on the code so I can share it with all of you sooner

Sunday, November 11, 2012

Prototypal inheritance decoration

Javascript is a mixed bag. You can use a functional style or you can do it with OO. When you do OO you can use prototypal inheritance or you can use it with classical inheritance (it still uses prototypes but the pattern is more classical). I usually use Classical inheritance because it is well understood, performs well and because it's embedded in Closure Tools. But like OO and functional styles we can mix the two together, so should we always stick to one type? If you read my last post then you know there are new features coming for PlastronJS, and one of them in particular has started me thinking about using the prototypal inheritance.

mvc.Collection will soon be changed so that it will not have sort order, instead to apply a filter or a sort order you will need to make a new object. However I want that new object to still have the same features as mvc.Collection and in particular if you add a new model to the new object I actually want it to be put on the original collection. I'm basically decorating the mvc.Collection with new functionality (kind of like decorating a function). To do this with classical inheritance I would need to create a class for these new functions, pass in the collection and reproduce each of the functions to call the corresponding function on the collection. This would be nice and easy using the new Proxy object as I could just say if the name doesn't exist on the object then try call it on the collection, but it's not supported everywhere yet. So what I really want to do is put the collection in the prototype chain and here is where the fun begins.

inheriting


let's call the mvc.Collection class A. I create a new collection: a

now I'd like to have an mvc.Filter class B. What I need to do is something like this:

F = function();
F.prototype = a;
f = new F();
B.prototype = f;
B.prototype.collection_ = a;
b = new B();

I could just as easily have done: B.prototype = a; but the issue is then any methods I put on B.prototype might overwrite a's methods. I've also put in collection_ so I have a reference directly to the collection. So how does this differ from the current use of goog.inherits for classical inheritance? Well the biggest difference is that we're seting the prototype to an instantiated object rather than just the prototype of a class which means we now have access to the instance properties.

this

now the tricky bit. "this" will refer to the object that I call. So if I have b then any time I call:

b.method();

then this will point to b. That isn't an issue if you're worried about getting/setting items that are only on b, but what about when we want to access and change items on our original collection? Well we're safe as long as we don't use '='. Here is the problem:

a.a = '1';
a.inc = function(num) {
  this.a = this.a + 1;
};
a.inc(); // b.a == 2 - number is from object 'a';
b.inc(); // b.a == 3 - number is from object 'b';
a.a; // 2

when we called inc we did it with the context being 'b'. Because we used the assignment operator we created a new property on the instance of 'b', effectively hiding the property of 'a' which is what we really wanted to change. We can either redefine any method on B to call itself on the collection (so the collection becomes the context) which may be a pain or we can instead design A to never use the assignment operator (after the constructor).

No More Assignments

There does have to be some assignments obviously, but you should try to restrict these to the constructor, or on scoped variables (variables without a preceding "this"). But how can that be done? What if I wanted to do something like this:

A = function() {
  this.country = 'USA';
}

a.setCountry = function(country) {
  this.country = country;
}

a.getCountry = function(country) {
  return this.country;
}

The problem here is that country is a simple type that can not be changed. If we do anything to a string the system creates a new object in memory and points to that. We want the 'this.something' to point to the same bit of memory and there are two types that work like that: objects and arrays. So we have two options:

A = function() {
  this.country = ['USA'];
}

a.setCountry = function(country) {
  this.country[0] = country;
}

a.getCountry = function(country) {
  return this.country[0];
}

// or

A = function() {
  this.country = {val: country};
}

a.setCountry = function(country) {
  this.country.val = country;
}

a.getCountry = function(country) {
  return this.country.val;
}

You may think that you could get away with wrapping any simple mutable properties you're putting on an object like this:

A = function() {
  this.properties = {
    prop1: 'a',
    prop2: 'b'
  }
};

but this makes it difficult if you have a chain of objects each with it's own property object. Instead of just getting b.property[0] you will have to recurse through all the prototypes looking in each 'properties' object until you find the one you need, rather than just letting javascript go up the chain for you.

This looks like a fair bit of effort, and it is, but hopefully you won't have too many mutable properties on an object. There is another step of complication though, what about objects and arrays.

object and array setting

In mvc.Collection it currently will make an unsafe copy of the attributes so they can be compared. This means we have something like:

this.prev_ = goog.unsafeClone(this.attr_);

which you can see is an assignment. However there is a lot of setting of the attr_ object and I wouldn't like to put it all under another array or object. If you're using an array or object then you can instead set them by clearing all the keys/values and copying over the keys/values from the other object. This has the unfortunate side affect that your new set object will not satisfy a comparison with the original object.

Calling the super


calling methods on the super should be pretty easy actually, just put in this.collection_.mehod() and you're done

And that's about it - the real trick is knowing what 'this' pertains to.

Monday, November 5, 2012

The Future of PlastronJS

It's been a little while since I wrote something about PlastronJS and although it isn't old I've had time to consider it's direction. There has been a lot of features added to the code recently and there is more coming, here are a few that are either in or looking to be put in the next month:

mvc.Layout

mvc.Control gives you some great functionality on top of goog.ui.Component as well as hooking up a model. But what if you want all that goodness without a model? Well now mvc.Layout inherits from goog.ui.Component and mvc.Control inherits now inherits from mvc.Layout. This means that you can use this.getEls, override addChild using this.placeChild_ and most importantly use the component level event system (this will be improved even more in the near future).

Dot property get/set/bind

In the same release as mvc.Layout comes dot property access. Ever wanted to listen to changes like this:

this.bind('address.country', function(country) {...});

You can even use get and set with dot property access, and all properties of an object that have changes below them will be enumerated:

a = new mvc.Model({'a': {'a': 1, 'b': 1}});
a.get('a.a'); // 1
a.bind('a', function() {alert('a');});
a.bind('a.a', function() {alert('a.a');});
a.bind('a.b', function() {alert('a.b');});
a.set('a.a', 2, true);
a.getChanges(); // ['a', 'a.a'];
a.change(); // alert a, alert a.a - but won't alert a.b

Also now any objects set will use a recursive check for changes by default.

One last handy thing is that this will even work with objects returned by computed properties.

Router ordering

Now the router will only run the first route that matches - also a route will not run when it's been added, you should run router.checkRoutes() when all routes have been added to fire the first time.

mvc.View

And now we move to the future. mvc.View will be an interface that much like that described in http://modernjavascript.blogspot.com/2012/06/v-in-mvc.html It will act almost like an mvc.Model where you can get and set and bind to changes. This means that the view itself will have an extra layer - or you could even use an mvc.Model as an mvc.View and bind two of them together with a control. I'll be providing some examples of how it could be used, but the possibilities are almost endless. One of the first implementations I will make will go through the DOM and use attributes on nodes to let the mvc.View know what data should be provided and how it should be interacted with (much like the in HTML binding clues given by Ender, Knockout or Angular). Another will be form based, and there will even be one that can aggregate views together. I'm hoping that I can show the flexibility and power of this idea in the near future.

mvc.Pool and filters/ordering

mvc.Collection is great but it is limited to only having one set of models and one sort order at a time. There will be a new model type soon that is a pool of models, like an unordered collection. What you can do beyond this is have something that inherits from mvc.Model and will have a filter and order that can be imposed on a pool that is passed to it. This means that if you have one set of models in a pool you can create two different order and give the pool to each, they will then both respond as if they were a collection but the pool will still manage it's own sync, only the filtering and sorting will be done by the object, the rest (like adding models) will be passed along to the pool. If you want to change sort order on a control you can do so by creating a new filter/sort, passing the pool in to that and setting the model of the control to the new filter/sort. Most likely mvc.Collection will actually become the filtering/sorting and if you instantiate it with models it will create a new mvc.Pool so that it is backwards compatible.

I'm planning to keep backwards compatibility with all these new features and improvements as well as going back over the code and improving it, so don't be afraid to dive in now and offer any suggestions as to what you'd like to see.


Wednesday, October 17, 2012

Finding Closure from jQuery - lessons learned

Yesterday I spoke about an easier method to starting with Closure Tools, you can get the slides here:

http://rhysbrettbowen.github.com/closure_from_jquery/

and the demo you can see in action here:

http://rhysbrettbowen.github.com/weatherdemo/

But what I'd like to talk about are some lessons I've learned, mistakes I made and what I'm going to change for the next time.

My spot to talk was on the second day as the second session after lunch. The second day is hard to get interest going and even harder to keep people awake, they've had an after party the night before and the food is settling nicely in their stomachs from lunch.

My first major mistake I made was to leave the lights off. I did this because the speaker before me had turned them off so I decided to leave it. Not a great thing to do when trying to command the attention of a room of sleepy people.

Another major mistake was how technical my speech was. I wanted to get some core concepts across like how goog.ui.component worked and I went in to too much detail. I showed code and where to put things, a better option would be to have a flow chart of it's lifecycle. Another big issue was that I showed goog.ui.component but what I actually used was mvc.Control which inherits from it. I should have just mentioned the inheritance as an aside and explained it all as if it was part of mvc.Control (from plastonjs).

I also wanted to mention the gotchas of programming to make things AO compatible and I gave two examples. I spent way too much time on the second one (a class variable) when it doesn't come up that often. I should instead have just left it out and put in a quick mention of that being the reason for $$ in the G.

I also went the wrong way about showing code. I showed the entire program, then the entire code. and tried to relate it back to parts of the program. I worked bottom up, showing code first then what it did second. I should have broken down the program in to segments, showed that segment then showed the code for it. That way it would be broken up a bit better.

Also I need to find a better way to describe the benefits rather than diving in to technical details. A presentation is not a classroom, it's a way to get people excited enough to go and find out for themselves. For this I think I need a flashier demo and to show off the compilers compression rather than just tell them it is good. (in case you're wondering here is what I should have shown:)

This shows the gzipped sizes of the javascript needed for each todomvc app at todomvc.com. CanJS doesn't have routing and I actually went through to websites to find the minimized size of javascript libraryies when the unminimized was provided. I left the actual coding for the app unminimized if it wasn't minimized already, but as these were between 1-7kb total I don't believe it would have a great impact on the final result.

So what am I going to do? I'm going to spruce up the presentation and show how each component is built one at a time. I'm not going to focus on closure tools and how it works - just it's advantages and how to get started using plovr, the G and PlastronJS - the actual diving in to closure library can come later once the excitement is there.

Tuesday, October 9, 2012

Breaking it down with algorithms II: Fibonacci

This series of posts is designed to not only explain how some algorithms work but also how you can think about problems to come up with your own algorithms.

the Fibonacci series is used in teaching Computer Science as it translates well in to a recursive solution - even if the solution is not ideal. The Fibonacci series starts with a 0 and 1, then each following number is worked out by taking the sum of the two previous numbers. This gives us the formula of:

Fib(n) = Fib(n-1) + Fib(n-2)

The reason it's used is because that's already a recursive function and looks something like this:

To look at performance of below solutions you can check out: http://jsperf.com/fibonacci-y-combinator/5

The Recursive Solution:

var Fib = function(n) {
  if (n <= 1)
    return n;
  return Fib(n-1) + Fib(n-2);
}

We can see that if given a formula we can write it out almost as we were give - with the exception of adding in the base conditions. We do have to be careful though as this will duplicate our work, we can see this by putting Fib(n-1) = Fib(n-2) + Fib(n-3) in to our original formula:

Fib(n) = Fib(n-1) + Fib(n-2)
Fib(n) = Fib(n-2) + Fib(n-3) + Fib(n-2)

As you can see we are doing Fib(n-2) more than once, and as we recurse through we will have a lot more duplication of effort. To fix this we instead will memoize our answers so instead of calling back through the recursive chain we will cache answers and return them when we get them back. We can make a general memoize function like so:

var memoize = function(fn) {
  var cache = {};
  return function(arg) {
    if (arg in cache) return cache[arg];
    cache[arg] = fn(arg);
    return cache[arg];
  };
}

So if we do this:

FibMem = memoize(Fib);

We should see a large performance gain. But this basically only puts us on a par with a linear algorithm and we are keeping all of the answers in memory. The great thing about it though is that if we want to work out different numbers several times, at least some of the work will be done for us. However if we want to print out the series of Fibonacci numbers instead of the nth one, then a linear equation should be better.

The Linear Equation

var Fib = function(n) {
var a = 0;
var b = 1;
for(var i = 0; i < n; i++) {
  var temp = b;
  b = a + b;
  a = temp;
}
return a;
}

And this is a good first attempt. For each loop we move along one until we get our answer. This is a pretty easy one to get so I'm going to move on to an optimization that I haven't seen a lot:

The Fast Loop


var Fib = function(n) {
var half = Math.floor((n-1)/2);
for(var i = 0, a = 0, b = 1; i < half; i++,b+=(a+=b)) {}
return n%2==0 ? b : a;
}

or perhaps in a more readable form:

var Fib = function(n) {
var a = 0;
var b = 1;
for(var i = 0; i < n - 2; i += 2) {
  a = a + b;
  b = b + a;
}
if (n % 2)
  return a;
return b;
}

Now first off passing in 0 will give you the wrong number, but we'll ignore that for now. What we've done is change the loop to go two numbers at a time rather than one. Because we do this we can eliminate the need for a temporary variable and we're only doing two assignments to go up two spots rather than three assignments to go up one. If we used destructuring assignment we could change our original algorithm to work without a temporary variable, but because it's not in all versions of javascript it's unlikely you would consider using it as yet (though for those interested it would be [a, b] = [b, a+b]).

The trick with this is to see that once we did a = a + b then we could just do b = b + a to return our a and b to be the smaller and larger numbers respectively. So when you are looping through a series looks for shortcuts, can you calculate more than one variable at a time? if you're going through numbers can you use arithmetic instead of saving a temporary variable?

Divide and Conquer

This is interesting as we've been taught that divide and conquer methods are really good, and that's usually true. The one problem with what I'll show you is that the individual steps are so heavy that for most numbers you'll be calculating up to, it's just not worth it but the higher the number you're calculating the faster it will be and should eventually be faster than the other methods. To do this method we first of all have to know some math.

There is something called the Fibonacci matrix. this matrix will give us the Fibonacci number for N if we multiply itself N times.:

[1, 1] ^ N
[1, 0]

Then it's just a simple matter of using the divide and conquer for powers. The complexity for this algorithm comes in the matrix multiplication and the algorithm goes a little something like this:

//to find the nth number
//fibonacci identity
Fib = [1,1,1,0]
//multiply a 2x2 Matrix
function mult2x2(a,b){
 return(
  [ a[0]*b[0]+a[1]*b[2], a[0]*b[1]+a[1]*b[3],
    a[2]*b[0]+a[3]*b[2], a[2]*b[1]+a[3]*b[3]
  ]
 );
}
function fibRecurse(M,n){
  //if n is one return the identity
  if(n==1)
    return M;
  //get the value of fib^n/2 (divide)
  var fibSoFar = fibRecurse(M,Math.floor(n/2));
  //multiply the two halves (and multiply by 1 more if not an even number) (conquer)
  fibSoFar = mult2x2(fibSoFar,fibSoFar);
  if(n%2==1)
    fibSoFar = mult2x2(fibSoFar,Fib);
  return fibSoFar;
}

Which is far more complicated but will get faster compared to the other algorithms the higher the number.

Conclusion

There are a few other algorithms I won't go through, like the direct formula as it's not as interesting to disect how it works (at least for the purpose of trying to solve a problem) and the Y combinator as it's not generally useful in javascript. I hope that the above has made you think past the usual fibonacci solutions and things like the fast loop method above should make you think about algorithms you were taught and whether or not they are the best method. The more you think about old problems the more likely you will come to new solutions rather than just relying on a memorized method.

Fork me on GitHub