Mostly about Javascript, Ruby on Rails and other web stuff

If you are building a single page application memory leaks can be a real problem, specially if you are application is meant to stay on the screen for long periods of time without the user refreshing it.

In this post I want to show how you can effectively avoid these leaks when developing with CanJS.

When the control is initialised, we are listening to the window resize event (#1) and creating a timeout (#2). Everything is fine until the control is removed from the DOM.

When the element is removed from the DOM we will end up with a ghost object still listening for the resize event and still running an interval, even if there is nothing in the DOM.

If we don’t unbind the events properly the browser doesn’t have a way to know that our control object should be garbage collected. We have created a memory leak.

This gets even worst if we have an application that adds and removes a control several times, which is normal in an application with multiple views. In that case we just keep piling ghost objects potentially consuming a lot of memory and creating strange bugs as we have multiple unintended objects listening to the same events.

The CanJS way

Getting rid of the first memory leak is quite easy in CanJS, instead of binding the event manually like shown above, you use the special CanJS syntax:

123456789

varControl=can.Control({init:function(ele,options){},'{window} resize':function(){//... do something on resize}});

The {window} resize declaration tells CanJS to listen for the event we want but unbinding it automatically when the control is destroyed.

The destroy method

The second leak has to be removed a bit more manually:

1234567891011

varControl=can.Control({init:function(ele,this.interval=setInterval(function(){// ... do some polling },2000);},destroy:function(){removeInterval(this.interval);}});

We need to manually remove the interval in the destroy method of our control, the good thing is that we don’t need to call this destroy method manually if we follow the correct pattern below.

Destroying a control

CanJS will destroy a control automatically when its element is removed from the DOM. But you have to be sure that the element is removed, not just reused.

For example, this wouldn’t work:

123456

// Create a control using an existing element in the DOMvarcontrolA=newControlA($('existing-element'),{});// Later reuse the element for a different controlvarcontrolB=newControlB($('existing-element'),{});// This will not call destroy() on controlA

On the other hand, removing the element first will give us the behaviour we expect:

123456789

// Create a document fragment first // this will be used as the element for the new controlvarview=$('<div>');// Create the control, and pass the newly created element fragmentvarcontrolA=newControlA(view,{});// Append that newly created element to our container$('.my-app').append(view);

123456789

// Later when replacing this control make sure to remove the element first$('.my-app').empty();// Removing the control element will automatically call .destroy on your control// Repeat the process for the new controlvarview=$('<div>');varcontrolB=newControlB(view,{});$('.my-app').append(view);

By removing the elements entirely from the DOM, CanJS will trigger destroy and unbind the events. So that’s it, avoiding memory leaks is quite straight forward when following the right patterns.

varControl=can.Control({init:function(ele,options){this.person=newPerson();this.errors=newcan.Map();varargs={person:this.person,errors:this.errors};varview=can.view('view',args);this.element.html(view);},'form submit':function(){// get errors from person if anyvarerrors=this.person.errors();// pass the errors to our errors observablethis.errors.attr(errors,true);if(errors){console.log(errors);}else{// proceed to saving here}returnfalse;}});

Note how I create a errors can.Map and pass it to the view. This map will allow me to show any validation errors to the user. In form submit we retrieve the errors from the form (using the validation plug-in) and pass those errors to the errors can.Map.

people is a CanJS model list , birthdayThisMonth is a Mustache helper. This Mustache helper looks like this:

12345678910111213141516171819202122

birthdayThisMonth:function(people,options){varperson,bd,bdMonth,thisMonth;if(people&&people.length){varres=[];for(vara=0;a<people.length;a++){person=people[a];bd=person.attr('birthdate');bdMonth=newDate(bd).getMonth();thisMonth=(newDate).getMonth();if(bdMonth===thisMonth){// we want to display this birthday// so add this to the array// options.fn is a function that will return the final string using the mustache templateres.push(options.fn(person));}}// we have an array, but we need to return a stringreturnres.join(' ');}}

Then we just need to pass the helper to the view (or declare it as global helper):

In this example the class Car takes an engine dependecy, each time you want to create a car you have to pass an engine to it. This can easily become a cumbersome way of instantiating objects because you need to know a lot about your object just to create them. In this case I need to know that Car takes an engine and specifically which engine depending on the type of car I want to create.

To deal with this the suggested solution is to use an injector. See the definition in wikipedia. The injector is in charge of creating the instances you need and injecting the right dependecies.

Although this is a powerful pattern I believe it mostly an unnecessary complication, specially in dynamic languages like ruby. Let me explain why.

What do we want to achieve with DI?

The main reason for using DI is to be able to swap the dependencies of an object at run time, this is mostly useful for testing. To achieve this there is a dead simple way to do it without having to deal with the complexity of injectors.

The simple way to do it

Instead of passing the dependecy when instantiating an object, we can simply let the object have default dependecies.

The Node Client

varrequest=require('request');varQ=require('q');vardefX=Q.defer();// will be resolved when x arrivesvardefY=Q.defer();// will be resolved when y arrivesvaroneAndTwo=Q.all([defX.promise,defY.promise]).then(processConcat);varbaseUrl="http://localhost:8080";request(baseUrl+'/x',makeValueHandler(defX));request(baseUrl+'/y',makeValueHandler(defY));

I create two deferreds: defX and defY. Then I create a promise that is the combination of defX and defY.

Immediately after that I make the first two calls to the server in parallel. When those to calls are done the deferreds will be resolved and the function processConcat will be called with the results (in the correct order).

The JavaScript code is not complex but is not completely straightforward either, you still need to scan up and down when reading the source code to understand exactly what is happening.

Here we create two channels (a way of communicating when using concurrent processes in Go), one for value x and the other for value y.

Immediately after that we fetch the values from the server but using the special go keyword. This means that those call will be made in their own processes so they will not block. These two requests happen in parallel.

The next two lines wait for the results of the API calls, the results are communicated using the channels.

The Go code looks a lot like typical sync code but still it is all happing in parallel thanks to the goroutines. So this code is as fast (event faster) than the Node version but simpler to understand IMO.

Conclusion

I am excited about Go, it has a lot to offer in multiple spaces. I will like to explore how something like Node Streams will look in Go.

There is a typical progression when developing an application. First we start with something simple, with a few models, things are simple to test. At this stage we can afford to build all the objects we need in our test without too much concern for speed and complexity.

123456

describeUserdolet(:user){User.new(name:‘John’)}it"has a name"doexpect(user.name).toeq(‘John’)endend

But soon things get complicated, we add more and more models to our application that depend on each other. Tests reflect this as well, we have to create a lot of objects in our tests to test simple things.

123456789101112

describeUserdolet(:english){Language.new(name:‘English’)}let(:australia){Location.new(name:‘Australia’,language:‘english’)}let(:melbourne){Location.new(name:‘Melbourne’,parent:australia)}let(:office){Workspace.new(name:‘MelbourneOffice’,location:melbourne)}let(:user){User.new(name:‘John’,workspace:office)}it"has a language"doexpect(user.default_language).toeq(english)endend

The example above creates all the objects that are needed to test user.default_language. We need to know a lot about our application just to run a test. Soon our test become a burden to write and very slow to run.

Mocks, Stubs!

It is evident that we are just doing too much in our test, we should just be creating the object we care about and mock the rest. Let’s rewrite this using doubles and stubs:

1234567891011121314

describeUserdolet(:english){double.as_null_object}let(:office){double.as_null_object}let(:user){User.new(name:‘John’,workspace:office)}beforedooffice(:language).and_return(:english)endit"has a language"doexpect(user.default_language).toeq(english)endend

This is faster and simpler, we are just creating the object under test (user) and doubles for the other objects. We don’t need know about all the relationships in our application, just knowing the interface we care about in the objects directly related is enough. In this case just knowing that office responds to language is all we need.

But there is of course a problem. What happens in office doesn’t respond to language anymore? Say that someone changes office.language to office.default_language. Our test will still pass! We have created an alterative universe in our test.

Integration test

Many experience developers will tell us that the solution to this conodrum is to have good integration test. That is partially true, integration tests are likely to fail when the interface between the objects is changed.

But guess what will happen? We will go and fix the integration test and then we will back to green. But wait, we forgot to fix the unit tests but everything passes! Unfortunatelly we cannot rely on due dilligence of people fixing all that should be fixed.

Now we are even in a worst situation, our tests are all green but our app is broken. So integration tests are not a reliable solution.

Your application:

Safe mocking / stubbing

We still want the benefits of lean, fast tests but without the dangers of alternative realities. So what is the solution?

I found that safe testing libraries are the best solution out there. This library will take care of checking that the methods you call actually exist in the mocked object. This frees us to still use doubles and stubs in our test without worring about the possibility of getting out of sync with the real application.

describeUserdofake(:english){Language}fake(:office){Workspace}let(:user){User.new(name:‘John’,workspace:office)}beforedostub(:office).language{english}endit"has a language"doexpect(user.default_language).toeq(english)endend

Bogus will check that office.language is an actual method and that it takes the number of parameters we send. In this way we can have the benefits of stubbing and mocking without the drawbacks. I highly recommend that you try it in your project.

But this doesn’t work, it throws angular into an endless loop, because it tries to render the collection directive regardless if the member has children or not.

So instead you need to add the collection directive manually only if there are children, thus the link function:

123456789

link:function(scope,element,attrs){//check if this member has childrenif(angular.isArray(scope.member.children)){// append the collection directive to this elementelement.append("<collection collection='member.children'></collection>");// we need to tell angular to render the directive$compile(element.contents())(scope);}}

Note the line $compile(element.contents())(scope);. As the html is appended manually we need to tell angular to re-render the directive.

Recently I was trying to find out a way of sharing some business logic between the client and the server. We have a reactive UI where results get calculated as you change values. These are complex formulas we rather not write in both Ruby and JavaScript so we don’t have to maintain them in two places.

The easiest solution would have been to make ajax calls to the server with the parameters get the results. But we wanted a UI that reacts immediately so needed to have the code loaded in the browser.

So this a solution I come up with, in summary:

Formulas are stored as plain JavaScript

Ruby Models load and use those formulas using V8

The formulas are served to the front end as partials

Here is a rundown of what I did step by step. I will use a simple interest formula in this example.

Storing the formulas

I needed the formulas to be accessible as partials so I added them in the view folder:

In app/views/formulas/_interest.js

123

functionformula(principal,rate,years){returnprincipal*rate*years;}

Using the formulas in my Ruby models

In order to run the JavaScript on the server you will need therubyracer gem, in Gemfile:

The JavaScript code is loaded inside the interest method and ran with the provided parameters. In this way the code is accessible as a plain ruby method and only needs to be tested in one place. In my test:

123456789101112131415

require'spec_helper'describe"Contract"dolet(:principal){100}let(:rate){0.5}let(:years){5}let(:contract){Contract.new(principal,rate,years)}it"returns the right interest"doexpect(contract.interest).toeq(250)end...end

Loading the formulas in the front-end

I couldn’t find a way of injecting the JS code into the assets pipeline, so instead I just loaded in a partial that gets loaded in the application layout.

This piece of JavaScript creates a global object APP if not found, then an object formulas inside APP and finally adds my interest formula to APP.formulas.interest.

Using the formulas in the front end

Once the formulas are loaded as shown above they can be used as:

1

varres=APP.formulas.interest(principal,rate,years);

So this is a way of sharing code between the back and the front end. If you how how could be improved or of a cleaner way altogether I would love to hear about it, maybe some DSL that can be used in both places.

Selecting a JavaScript MVC framework can be hard work. There are so many factors to consider and so many options out there that selecting a framework can be overwhelming. To have an idea of all the possible alternatives have a look at TodoMVC.

I have had the opportunity to use four of these frameworks: Angular, Backbone, CanJS and Ember. So I decided to create a comparison to help you decide which one to use. I will go through several factors that you might want to consider when choosing one.

To each factor I have assigned a score between 1 and 5. Where 1 is poor and 5 is great. I have tried to be impartial in my comparison, but of course my objectivity is heavily compromised as the scores are based mostly on my personal experience.

Features

There are really important features a framework should have to provide the necessary foundation to build useful applications. Does it do view bindings? two way bindings? filters? computed properties? dirty attributes? form validation? etc. This can be a very long list. Below is a comparison of what I consider the really important features in a MVC framework:

Feature

Angular

Backbone

CanJS

Ember

Observables

y

y

y

y

Routing

y

y

y

y

View bindings

y

y

y

Two way bindings

y

–

y

y

Partial views

y

–

y

y

Filtered list views

y

–

y

y

Observables: Objects that can be observed for changes.

Routing: Pushing changes to the browser url hash and listening for changes to act accordingly.

View bindings: Using observable objects in views, having the views automatically refresh when the observable object change.

Two way bindings: Having the view push changes to the observable object automatically, for example a form input.

Partial views: Views that include other views.

Filtered list views: Having views that display objects filtered by a certain criteria.

Update 2014-07-08: As of version 2.0 CanJS now supports two way bindings.

Scores

So based on these features my scores are:

Angular

Backbone

CanJS

Ember

5

2

4

5

It is important to note that Backbone can do most of this things with a lot of manual code or with the help of plug-ins. But I am only considering the available features in the core framework.

Flexibility

There are hundreds of awesome plug-ins and libraries out there that do specialised things. They usually do these things better than what comes bundle with a framework. So it important to be able to integrate these libraries with the chosen MVC framework.

Backbone is the most flexible framework as it is the one with the less conventions and opinions. You are required to make a lot of decisions when using Backbone.

CanJS is almost as flexible as Backbone as it allows you to easily integrate other libraries with minimum effort. With CanJS you can even use a totally different rendering engine if you want, I have used Rivets extensively with CanJS without any issues. Although I recommend using what comes with the framework.

Ember and Angular are still flexible frameworks to some degree but you will find that you could end up fighting the framework if you don’t like the way it does certain things. There are some things that you just need to buy into when using Ember or Angular.

Angular

Backbone

CanJS

Ember

3

5

4

3

Learning curve and documentation

Angular

Angular has a very high wow factor at the beginning. It can do some amazing things – like two-way bindings – without having to learn much. And it looks quite easy at first sight. But after you have learnt the very basics it is quite a steep learning curve from there. It is a complex framework with lots of peculiarities. Reading the documentation is not easy as there is a lot of Angular specific jargon and a serious lack of examples.

Backbone

The basic of Backbone are quite easy to learn. But soon you find that there are not enough opinions there to know how to best structure your code. You will need to watch or read a few tutorials to learn some best Backbone practices. Also you will find that you will probably need to learn another library on top of Backbone (e.g. Marionette or Thorax) to get things done. So I don’t consider Backbone the easier framework to learn.

CanJS

CanJS is in comparison the easiest to learn of the bunch. Just by reading the one page website (http://canjs.us/) you will know most of what you need to be productive. There is of course more to learn, but I only had the need to reach for help in rare occasions (tutorials, forum, irc).

Ember

Ember also has a steep learning curve like Angular, I believe that learning Ember is easier than Angular but it requires a highest learning investment at the beginning to get basic things done. Angular in contrast lets you do some amazing things without learning too much. Ember lacks this early wow factor.

Scores

Angular

Backbone

CanJS

Ember

2

4

5

3

Developer productivity

After you learn the framework well what really matters is how productive you are with. You know: conventions, magic, doing as much as possible quickly.

Angular

Once you know Angular well you be can very productive with it, no doubt about that. It just doesn’t get the highest score because I think that Ember has gone a step further in this category.

Backbone

Backbone requires you to write a lot of boilerplate code, which I think is totally unnecessary. This is in my opinion a direct threat against developer productivity.

CanJS

CanJS neither shines nor disappoints in this area. But due to the low learning curve you can be quite productive with it very early on.

Ember

Ember really shines here. Because it is full of strong conventions it does a lot of stuff automagically for you. All you need to do is learn and apply those conventions and Ember will to the right thing.

Scores

Angular

Backbone

CanJS

Ember

4

2

4

5

Community

How easy is to find help, tutorials and experts?

The Backbone community is huge, there is no doubt about that. You can find dozens of tutorials about Backbone, a very active community on StackOverflow and IRC.

The Angular and Ember communities are pretty big as well. Also lots of tutorial and activity in StackOverflow and IRC, but not as much as Backbone.

The CanJS community on the other hand is small in comparison, but fortunately is quite active and helpful. I haven’t found the smaller size of the CanJS community to be a liability.

Angular

Backbone

CanJS

Ember

4

5

3

4

Ecosystem

Is there an ecosystem of plug-ins and libraries?

Here again Backbone beats the others hands down. There are tons of plug-ins for it. The Angular ecosystem is getting quite interesting as well with things like Angular UI. I think that the Ember ecosystem is less developed but it should get better due to Ember’s popularity. CanJS has the smallest ecosystem if any.

Angular

Backbone

CanJS

Ember

4

5

2

4

Size

This might be an important consideration, specially if you are doing mobile development.

Size library alone (no dependecies, just min)

Angular

Backbone

CanJS

Ember

80k

18k

33k

141k

Backbone is the smallest and people often point to this fact. But this is not the end of the story.

Size with dependencies

At 80k Angular is the only library of the bunch that doesn’t require extra libraries to work.

However all the other need other libraries to work:

Backbone needs at least Underscore and Zepto. You can use the mini-templates in underscore for rendering views, but most of the time you will want to use a nicer template engine like Mustache. This is 61K.

Scores

Angular

Backbone

CanJS

Ember

4

5

5

2

Performance

I don’t consider performance to be a critical factor on choosing a framework because they are all performant enough for most of the things they will be used for. But this of course depends on what you are doing with it. If you are building a game performance should be a big consideration.

I have seen and made many performance tests with these libraries e.g. this one. But I am not totally convinced on the reliability of these tests. It is really hard to be sure that the test is really testing the right things and in the right way.

However, from what I have seen and read CanJS seems to have the edge when it comes to performance, specially in rendering view bindings. On the other hand I believe that Angular is the less performant based on the fact that it does dirty checking of objects. This cannot possibly be as performant as the others. See this.

Scores

Angular

Backbone

CanJS

Ember

3

4

5

4

Maturity

Is this a mature framework, has it been proven in production, are there many website using it?

Backbone has a ton of websites built with it. Its code base hasn’t had major changes in the lasts two year which is a great thing from the maturity perspective.

Although Ember is not that new, it has had major changes along the way, just reaching a stable form in the last couple of months. So at this time I don’t consider it to be a mature framework.

Angular seems more stable and proven than Ember. But not as much as Backbone.

CanJS may seem like an unproven solution because you cannot find a ton of site built with it. But CanJS comes with a lot more backing than what you first perceive. CanJS is an extraction of JavaScriptMVC a library that has been around since 2008 and has lots of experience build in.

Angular

Backbone

CanJS

Ember

4

5

4

3

Memory leak safety

This is an important consideration if you are building single page apps that are intended to stay open for a long time. You don’t want your application to leak memory, this can be a real problem. Unfortunately this can happen quite easily, specially if you are creating listeners for DOM events yourself.

Angular, CanJS and Ember will deal with this effectively as long as you follow their best practices. Backbone on the other hand requires you to do this work manually in a teardown method.

Angular

Backbone

CanJS

Ember

5

3

5

5

Testability

How easy is to test you code?
The keys to have great testable code are modularity (have small pieces that can be tested in isolation) and dependency injection (being able to change dependencies in your tests).

You can do this with any of the frameworks if you learn the right patterns, but it is not easy and it requires you to get out of your way to apply them.

Modularity and dependency injection are core features of Angular, it actively discourages you from doing things in any other way. This usually leads to code that is easier to test. Because of this I consider Angular to has an advantage in this area.

Do you want a framework that stick closely to the original SmallTalk MVC pattern? –> None here, maybe CanJS is the closest.

Do you want to use what seems cool at the moment? –> Ember, Angular

There is no way to score this.

Tally

Well, putting all together this is my tally. Remember this is just my opinion, please let me know if you think I have scored a library really wrong.

If you put the same weight to every factor it is a tight competition, there are no clear winners or losers. So I guess it all comes down to personal taste or how much weight you apply to each particular factor.

A note about Backbone (Impartiality ends here)

I have tried to stay impartial during my post but I cannot finish it without sharing my current opinion about Backbone.

Backbone was a great library two years ago, but I am convinced that there are better things now. I believe that many people choose Backbone just because of its popularity, it is a vicious circle.

Backbone trumps ultimate flexibility over developer convenience. But I think that it has traded too much, as it seriously lacks features and developer productivity. Yes, there are lots of plug-ins to compensate for this, but then you will be learning Backbone and something else on top.

Backbone can also be very tempting because of its big community and the ecosystem, but this advantage will disappear as the other frameworks become more popular.

Because of this I strongly feel that you should think twice before choosing Backbone for your next project.

Update 2013-04-20: Added testability.
Update 2013-04-18: Made it clear that the last section is just my opinion. Removed the inflammatory “It is time to move on” statement.

When I first started learning about JavaScript object model my reaction was of horror and disbelief. I was totally puzzled by its prototype nature as it was my first encounter with a prototype based language. I didn’t help that JavaScript has a unique take on prototypes as it adds the concept of function constructors. I bet that many of you have had similar experience.

But as I used JavaScript more I didn’t just learn to understand its object model but also started love parts of it. Thanks to JavaScript I have find out the elegance and flexibility of prototypes languages. I am now quite fond of prototype languages because they have a simpler and more flexible object model than class based languages.

Prototypes in Javascript

Most guides / tutorials start explaining JavaScript objects by going directly to ‘constructor functions’, I think this is a mistake, as they introduce a fairly complex concept early on making Javascript look difficult and confusing from the start. Let’s leave this for later. First let’s start with the basics of prototypes.

Prototype chains (aka prototype inheritance)

Every object in Javascript has a prototype. When a messages reaches an object, JavaScript will attempt to find a property in that object first, if it cannot find it then the message will be sent to the object’s prototype and so on. This works just like single parent inheritance in a class based language.

Prototype inheritance chains can go as long as you want. But in general it is not a good idea to make long chains as your code can get difficult to understand and maintain.

The __proto__ object

To understand prototype chains in JavaScript there is nothing as simple as the __proto__ property. Unfortunately __proto__ is not part of the standard interface of JavaScript, not at least until ES6. So you shouldn’t use it in production code. But anyway it makes explaining prototypes easy.

12345678910111213141516171819202122232425

// let's create an alien objectvaralien={kind:'alien'}// and a person objectvarperson={kind:'person'}// and an object called 'zack'varzack={};// assign alien as the prototype of zackzack.__proto__=alien// zack is now linked to alien// it 'inherits' the properties of alienconsole.log(zack.kind);//=> ‘alien’// assign person as the prototype of zackzack.__proto__=person// and now zack is linked to personconsole.log(zack.kind);//=> ‘person’

As you can see the __proto__ property is very straightforward to understand and use. Even if we shouldn’t use __proto__ in production code, I think that these examples give the best foundation to understand the JavaScript object model.

You can check that one object is the prototype of another by doing:

12

console.log(alien.isPrototypeOf(zack))//=> true

Prototype lookups are dynamic

You can add properties to the prototype of an object at any time, the prototype chain lookup will find the new property as expected.

1234567891011121314

varperson={}varzack={}zack.__proto__=person// zack doesn't respond to kind at this pointconsole.log(zack.kind);//=> undefined// let's add kind to personperson.kind='person'// now zack responds to kind// because it finds 'kind' in personconsole.log(zack.kind);//=> 'person'

New / updated properties are assigned to the object, not to the prototype

What happens if you update a property that already exists in the prototype? Let’s see:

1234567891011121314

varperson={kind:'person'}varzack={}zack.__proto__=personzack.kind='zack'console.log(zack.kind);//=> 'zack'// zack now has a 'kind' propertyconsole.log(person.kind);//=> 'person'// person has not being modified

Note that the property ‘kind’ now exists in both person and zack.

Object.create

As explained before __proto__ is not a well supported way of assigning prototypes to objects. So the next simplest way is using Object.create(). This is available in ES5, but old browsers / engines can be shimmed using this es5-shim.

12345678

varperson={kind:'person'}// creates a new object which prototype is personvarzack=Object.create(person);console.log(zack.kind);// => ‘person’

You can pass an object to Object.create to add specific properties for the new object

Yes, the object you need to pass is a bit convoluted, but that is the way it is. See the docs here.

Object.getPrototype

You can get the prototype of an object using Object.getPrototypeOf

12

varzack=Object.create(person);Object.getPrototypeOf(zack);//=> person

There is no such thing as Object.setPrototype.

Constructor Functions

Constructor functions are the most used way in JavaScript to construct prototype chains. The popularity of constructor functions comes from the fact that this was the only original way for constructing types. It is also an important consideration the fact that many engines are highly optimized for constructor functions.

Unfortunately they can get confusing, they are in my opinion one of the main reasons why new comers find JavaScript puzzling, but they are a big part of the language and we need to understand them well.

Functions as constructors

In JavaScript you create an instance of a function like this:

123456

functionFoo(){}varfoo=newFoo();//foo is now an instance of Fooconsole.log(fooinstanceofFoo)//=> true

In essence functions when used with the keyword new behave like factories, meaning that they create new objects. The new object they create is linked to the function by its prototype, more on this later. So in JavaScript we call this an instance of the function.

‘this’ is assigned implicitly

When we use ‘new’, JavaScript injects an implicit reference to the new object being created in the form of the ‘this’ keyword. It also returns this reference implicitly at the end of the function.

When we do this:

123456

functionFoo(){this.kind=‘foo’}varfoo=newFoo();foo.kind//=> ‘foo’

Behind the scenes it is like doing something like this:

12345678

functionFoo(){varthis={};// this is not valid, just for illustrationthis.__proto__=Foo.prototype;this.kind=‘foo’returnthis;}

But keep in mind that the implicit ‘this’ is only assigned to a new object when using ‘new’. If you forget ‘new’ keyword then ‘this’ will be the global object. Of course forgetting new is a cause of multiple bugs, so don’t forget new.

One convention that I like is capitalizing the first letter of a function when it is intented to be used as a function constructor, so you now straightaway to you are missing the new keyword.

The ‘function prototype’

Every function in JavaScript has a special property called ‘prototype’.

1234

functionFoo(){}Foo.prototype

As confusing as it may sound, this ‘prototype’ property is not the real prototype (__proto__) of the function.

1

Foo.__proto__===Foo.prototype//=> false

This of course generates a lot of confusion as people use the term ‘prototype’ to refer to different things. I think that a good clarification is to always refer to the special ‘prototype’ property of functions as ‘the function prototype’, never just ‘prototype’.

The ‘prototype’ property points to the object that will be asigned as the prototype of instances created with that function when using ‘new’. Confusing? This is easier to explain with an example:

12345678910111213141516

functionPerson(name){this.name=name;}// the function person has a prototype property// we can add properties to this function prototypePerson.prototype.kind=‘person’// when we create a new object using newvarzack=newPerson(‘Zack’);// the prototype of the new object points to person.prototypezack.__proto__==Person.prototype//=> true// in the new object we have access to properties defined in Person.prototypezack.kind//=> person

That is mostly everything there is to know about the JavaScript object model. Understanding how __proto__ and function.prototype are related will give you countless hours of joy and satisfaction, or maybe not.