Ian Cropper

developer

Filtering by Category: JavaScript

Can we all chill out with prototype?

I've been guilty of it, you've been guilty of it. Every JavaScript developer has been guilty of it. Using prototype everywhere

Look, I get it. We are told to never put functions and variables on the global namespace unless we have a damn good reason for it. Just having a var with no namespace and not attached to a prototype, it can feel dirty, but people please, let's use some discression. 

Have you ever inherited a project and EVERY. SINGLE. FUNCTION. in the JavaScript was attached to an object's prototype? Think about it for minute.....there it is, yes, you remember now. In order to  combat this terrible trend, lets start with some foundation.

What is prototype?

Protoypes are intelligent beings that live within all objects. 

Crap, no those are Midi-chlorians. Prototypes are similar though. Every object in JavaScript contains a prototype. Try it out. Open up the console and paste this in.


var obj = {test: "onetwothree"};
console.log(obj.__proto__);

Not convinced? Then try this.


console.log("".__proto__);

"Wait, even an empty string has a prototype?"

Sure does! If you expand the result, do you see all those properties and functions attached? They're attached to the prototype. Think of them as values attached to an object that every other object inherits from. 

So every object in JavaScript has a prototype. The most notable exceptions are:

  1. Integers
  2. undefined
  3. null

Now before you go thinking "oh, so primitives", no I don't mean that. Try it out. In the console, write:


4.__proto__;
undefined.__proto__;
null.__proto__;

Then write


4.0.__proto__;
true.__proto__;
NaN.__proto__;

I won't go further than that, but it's just interesting to keep in mind. Now where were we?

Oh yeah, So every object in JavaScript has a prototype. So when you create an object and assign something to it's prototype, your'e giving that object something that is accessible only through that object. It's through using prototype that we get the awesome advantages of inheritance in JavaScript. I'll save the inheritance discussion for another time though since this is a post about patterns. The important thing to remember is that once a value is assigned to an object's prototype, it can be accessed within the object using the syntax:

this.someFunctionOrProperty

Here's a simple example:


var util = function(){};
util.prototype.getAllDivs = function() {
	return $('div');
}
utl.prototype.addBorderToAllDivs = function() {
	this.getAllDivs().css("border", "1px solid black");
}
var u = new util();
u.addBorderToAllDivs();

 

The most important part of this post

Look really closely at the code above.

I want you to ask yourself this question: "Does getAllDivs need to be a part of util's prototype?"

WONDERFUL! YOU DID IT! NO! The answer is NO! It doesn't! 

Then why the hell do we write code like this? The answer is, because we love to be able to write the line 

this.getAllDivs()

With that "this" in front of the function call, we know that the function belongs to the object. We like that. It looks good, there's a sense of security there. But this is wrong wrong wrong. I once hacked an online game of Risk because the developer had put everything on the prototype. So when I found the function


.prototype.isAdjacentTo = function(){
  /*[lots of checks and other function calls]*/
} 

I just overrode it to be


.prototype.isAdjacentTo = function(){return true;}

And I was able to attack anyone from anywhere. I tried to convince the other players that I had earned so many points that I had been granted special abilities, but it didn't quite work out. The moderators didn't have any sense of humor.

How can we make that code better?

Let's take advantage of an awesome tool that's super easy to use in JavaScript: a self-executing function that creates a closure.


var util = function(){};
(function(){
    var getAllDivs = function(){
        return $('div');
    }
    util.prototype.addBorderToAllDivs = function() {
        getAllDivs().css("border", "1px solid black");
    }
})();
var u = new util();
u.addBorderToAllDivs();

BAM! exact same functionality, we still have a clean global namespace, and we didn't expose getAllDivs to the rest of the world.

NOTE:

Make sure you think of the "private" variables and functions inside the closure as singletons. The values of these fields will carry over between objects that use them. For example:

<pre class="line-numbers"><code class="language-javascript">
var util = function(){};
(function(){
    var count = 0;
    util.prototype.incrementAndGetCount = function() {
        return ++count;
    }
})();
var u = new util();
u.incrementAndGetCount(); //=> 1
var u2 = new util();
u2.incrementAndGetCount(); //=> 2
</code></pre>

What do I do with this new found knowledge?

You think with it. Rather than just slapping everything on an object's prototype, take a minute and think if it actually needs to be there. 

Remember, prototype is great for inheritance, so if something will never be extending the object, or an object's property will never be used outside of the object itself,  then maybe you don't need that value on the object's prototype.

How does AJAX work?

don't ask questions, just use $.ajax

Have you ever stopped to wonder "what the hell is going on there?" I love third-party libraries. There's no sense in reinventing the wheel every time you want to do something. AND, third party libraries help out a TON to prevent developers from implementing their own who-the-hell-knows-what for each task as it arises. However, when using a tool that does as much as $.ajax, it's probably important to have some idea of what's going on.

Quick! To 2006!

You might have missed it, but we just celebrated the 10th anniversary of $.ajax. In February of 2006, jQuery had ajax built into it and thus, we were relieved of every having to use the xhr object. 

"'xhr'? that sounds even cooler than 'ajax'".

It does indeed. If you thought Ajax sounds cool because it was named after Homer's Greek champion, I would congratulate you on knowing your literature, but smack you for not knowing your trade. "Ajax" stands for "Asynchronous JavaScript And XML". (Yes, it is very rare that the "And" actually makes it in the acronym.) 

XHR on the other hand stands for "Xml Http Request".

Remember, Ajax itself is not a tool, it's a process by which calls from the client are made to a server asynchronously. Ajax is the activity, XmlHttpRequest is the tool. Think of Ajax as "driving" and xhr is the car. It's what your dad used when he was writing JavaScript. And in the spirit of handlebar mustaches, flannel shirts, straight-blade razors, and Celtic tattoos all coming back into style, I wouldn't be surprised if the hipsters bring back using plain ol' XHR as well (cause jquery is just too mainstream).

Let's not get too far before providing the official Mozilla definition.

"XMLHttpRequest is an API that provides client functionality for transferring data between a client and a server. It provides an easy way to retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just a part of the page without disrupting what the user is doing.  XMLHttpRequest is used heavily in AJAXprogramming.
XMLHttpRequest was originally designed by Microsoft and adopted by Mozilla, Apple, and Google. It's now being standardized at the WHATWG. Despite its name, XMLHttpRequest can be used to retrieve any type of data, not just XML, and it supports protocols other than HTTP (including file and ftp)."

Let's compare

So lets start with what we know and love. jQuery. Though ajax in jQuery isn't set up with real Promises, it carries a promise kind of feel where you can chain bits of functionality together. Today, we write an ajax request like this.


var xhr = $.ajax({
url: "path/to/url",
  method: "POST", //or "GET"
  data: {data1: "foo", data2: "bar"}
}).done(function(response){
   //...do stuff if the call succeeds
}).error(function(err){
   //...do stuff if the call fails
}).always(function(al){
   //...do stuff if the call fails or succeeds
});

And there you have it! Simple ajax that works without you having the think about anything. You don't even need to know what the hell it does and it still works for you!

Now let's see how this would work without jQuery.


var xhr = new XMLHttpRequest();
xhr.open('POST', "path/to/url");
xhr.onload = function (response){
if(xhr.statusCode == 200){
 //...do stuff if the call succeeds
}else {
 //...do stuff if the call fails
}
//...do stuff if the call succeeds or fails
};
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));

If you're thinking "only people who worry about garbage collection and pointers would use that" I wouldn't totally disagree with you. BUT! In defense of those people, they do tend to be able to ninja things together that others might not think possible. AND, those people tend to write much much better code than you because they understand how things work in the background.

But How does it work?

Oh, right, your original question...

JavaScript is perhaps most beloved for it's non-blocking I/O powers. It does an amazing job telling other things to perform tasks while it moves on to other things. 

"Go take care of this job for me and let me know when you're finished."

This is made possible by JavaScript's event queue. It's essential a first-in-first-out collection of tasks that need to be taken care of. hen you set up an XHR object, you assign it data and you give it a function to perform upon completion. JavaScript's order of execution is centered around an event queue. As each task is completed, it move's on to the next task in line. (This is where the 'A' in Ajax comes from.)

So when the script hits the line "xhr.send([data]);", the browser kicks of an HTTP(s) request to the server with a special header added.

X-Requested-With: XMLHttpRequest

I don't want to go into the details of all the things this header does, so I'll just say for now that it allows the browser and server to determine which requests are page requests and which are Ajax requests which in turn allows for the policing of Cross Origin Request Sharing and prevention of Cross site request forgery.

Once the server has successfully sent back a response, either an error or a success, the onload function is placed in the event queue to be evaluated with the response from the server at the next possible opportunity.

To learn more about JavaScript's event loop, check out this explanation.

But What does Ajax even solve?

To get a full appreciation for Ajax, we have to go back. All the way back to the 90's, so grab your hair oil and scrunchies, cause it's gonna get real.

Netscape

If you remember using AOL or MSN Messenger, then you probably also using Netscape Navigator. It was a dark, dark time. A time full of static content, 90 degree angles, solid colors, and inline styles. 

To combat the drudgery and allow web pages to be more engaging, Netscape introduced "LiveScript" which allowed for more dynamic content. This was still the 90's though, so don't think it was anything too impressive, cause it was basic.

This was back in 1995. While Netscape is loosing market share, Microsoft's Internet Explorer is growing in popularity. When the dotcom bubble finally burst in March of 2000, research and development budgets dried up along with the jobs and no one really cared about dynamic content anymore. That is, except for a multi-billion dollar company headquartered in the Pacific North-West.

Microsoft

By the time the bubble had burst, there were already scripts being used within web pages, so don't go thinking that Microsoft picked up the Client-side scripting flag and charged on alone. What it did do though was create a protocol by which scripts within the web-page could interact directly with the server. Prior to this new development, if you wanted to get more data from the server, you had to request a totally new page with new data.

This would have sucked if all you wanted to do was view a new image from a gallery. 

making it ubiquitous 

Google's Gmail was one of the very first services to really take advantage of this new XMLHttpRequest technology and make it mainstream.

Even back in 2004, even with hundreds of emails getting sent to you, you would have no idea without refreshing the page. Ajax allowed Gmail to update part of the page without refreshing the whole site [src].

The XHR object changed web development more than anything else up to this point. Modules in a page can not be loaded lazily. Simple pieces of information can be posted immediately, typeaheads are possible, multi-leveled dynamic forms are possible. Yes....yes indeed. We do love Ajax.

 

So now you know why Ajax is so damn important and how it works; which means you know more than 90% of your coworkers.

 

Sources:

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

http://archive.wired.com/science/discoveries/news/2009/03/dayintech_0401

http://www.aaronsw.com/weblog/ajaxhistory

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest