Monday, 1 December 2008

Practical Prototype and script.aculo.us - Part4

Today i started reading Practical Prototype and script.aculo.us By Andrew Dupont.

Nice book written by Andrew Dupont.

I want to share few quotations i found from this book from next 2 chapters (7-8).

1) JavaScript is a multi-paradigm language.

2) Encapsulation

OOP helps keep things organized through bundling. An object contains all the methods and properties associated with it, minimizing clutter and affording portability.

3) Luckily, nearly anything can be done in JavaScript if you’re willing to hack at it long enough. Prototype features a Class object that can mimic most of the features of classbased inheritance. It’s not meant to change the way JavaScript works; it’s just a different approach to OOP—an extra tool to have on your belt.

4) Functions Can Have Their Own Methods

Imagine I’ve got a function that adds numbers together:

function sum() {
var num = 0;
for (var i = 0; i < arguments.length; i++)
num += arguments[i];
return num;
}

The sum function will add its arguments together and return a number. If no arguments are given, it will return 0.

We know the syntax for calling this method:

var result = sum();

To call this function, we append empty parentheses. If we take the parentheses off,though, we’re no longer calling the function—we’re just referring to it:

var result = sum;

Be sure you understand the difference. In the first example, result is set to 0—the result of calling sum with no arguments. In the second example, result is set to the sum function itself. In effect, we’re giving sum an alias.

var result = sum;
result(2, 3, 4); //-> 9

We’re going to look at a few instance methods of Function. At first, these may seem like magic tricks, but they’ll become more intuitive the more you use them.

Using Function#curry

Partial application (or currying) is a useful technique in languages where functions are first-class objects. It’s the process by which you "preload" a number of arguments into a function. In other words, I could "curry" a function that expects parameters a, b, and c by giving it a and b ahead of time—getting back a function that expects only c. Confused yet? What I just said is much easier to express in code:

function alertThreeThings(a, b, c) {
alert(a);
alert(b);
alert(c);
}

var alertTwoThings = alertThreeThings.curry("alerted first");

alertTwoThings("foo", "bar");

// alerts "alerted first"
// alerts "foo"
// alerts "bar"

We’ve just defined a function that, if we were to write it out ourselves, would behave like this:

function alertTwoThings(b, c) {
return alertThreeThings("alerted first", b, c);
}

But by using curry, we’re able to express this more concisely and flexibly.Function#curry can accept any number of arguments. I could load two or three arguments

into alertThreeThings:
var alertOneThing = alertThreeThings.curry("alerted first","alerted second");
alertOneThing("foo");

// alerts "alerted first"
// alerts "alerted second"
// alerts "foo"

var alertZeroThings = alertThreeThings.curry("alerted first","alerted second", "alerted third");

alertZeroThings();

// alerts "alerted first"
// alerts "alerted second"
// alerts "alerted third"

Using Function#delay and Function#defer

JavaScript has no formal “sleep” statement—no way to block all script execution for a specified amount of time. But it does have setTimeout, a function that schedules code to be run at a certain time in the future.

function remind(message) {
alert("REMINDER:" + message);
}

setTimeout(function() { remind("Be sure to do that thing"); }, 1000);

The built-in setTimeout function takes two arguments. The first can be either a function or a string; if it’s a string, it’s assumed to be code, and will be evaluated (with eval) at the proper time. (It’s much better practice to pass a function.) The second argument must be a number, in milliseconds, that tells the interpreter how long to wait before trying to run the code we gave it. It returns an integer that represents the timer’s internal ID; if we want to unset the timer, we can pass that ID into the clearTimeout function.

In this example, the setTimeout call ensures that the function we’ve passed it will get called at least 1000 ms (1 second) later. Because browser JavaScript executes in a singlethreaded context, the interpreter might be busy 1 second later, so there’s no way of knowing the exact moment. But nothing will slip through: as soon as the interpreter is idle again, it will look at the backlog of things that have been scheduled, running anything that’s past due.

5) The capitalize and truncate Methods

These methods format strings so that they’re fit for user consumption. String#capitalize will convert the first letter of a string to uppercase and all other letters to lowercase:

"never".capitalize(); //-> "Never";
"NEVER".capitalize(); //-> "Never";
"Never".capitalize(); //-> "Never";

String#truncate is quite interesting. It will return the first n characters of a string,along with an ellipsis to indicate the truncation:

var warning = "Never, never pour salt in your eyes."
var truncation = warning.truncate(15); //-> "Never, never..."
truncation.length; //-> 15

The first argument, naturally, indicates how long you’d like the resulting string to be. The optional second argument lets you specify a custom truncation, if you’re not a fan of the default (...). Keep in mind that the length of the truncation is included in the length of the returned string.

6) Using JSON

Strings are the building blocks of high-level protocols like HTTP. A client and a server communicate in plain text, which, while much less friendly than the rendered view of a browser, is nonetheless human-readable.

Each time your browser requests an HTML file, it receives one gigantic string, which it then converts into a tree of objects for rendering. It converts between the two according to the rules of HTML. It can be said, then, that HTML is a serializer: it takes something inherently nonlinear and makes it linear for storage purposes.

The interesting stuff is done at higher levels, with more complex data types. But on the Web, sooner or later, it all ends up as a string. JSON (JavaScript Object Notation) is simply a way to represent these complex structures as strings.

7) What Does JSON Look Like?

Prototype likes to leverage the literal syntax for object creation, so code like this should be nothing new to you:

var vitals = {
name: "Andrew Dupont",
cities: ["Austin", "New Orleans"],
age: 25
};

We can describe data structures in JavaScript with a minimum of syntactic cruft. By comparison, let’s see what this data would look like in XML:

<vitals>
<name>Andrew Dupont</name>
<cities>
<city>Austin</city>
<city>New Orleans</city>
</city>
<age>25</age>
</vitals>

XML is verbose by design. What if we don’t need its extra features? That’s where JSON comes in.

8) The Object.isArray, Object.isHash, Object.isElement Methods

The three remaining type-checking methods test for arrays, hashes (instances of Prototype’s Hash class), and DOM element nodes. Each of these would respond to typeof with "object," but this is unacceptable for arrays and DOM nodes in particular, since they’re among the most commonly used objects in the browser environment.

var amigos = ["Lucky", "Ned", "Dusty"];
typeof amigos; //-> 'object'
Object.isArray(amigos); //-> true
var villain = $('el_guapo');
typeof villain; //-> 'object'
Object.isElement(villain); //-> true
var partyFavors = $H({
cake: 1,
amigos: 3,
pinatas: "plethora"
});
typeof partyFavors; //-> 'object'

Object.isHash(partyFavors); //-> true

9) The reverse and clear Methods

The first two methods document themselves. Array#reverse inverts the order of an array; Array#clear removes all of an array’s items. Array#reverse returns a new array by default, but takes an optional Boolean argument to reverse the original array:

var presidents = ["Washington", "Adams", "Jefferson", "Madison", "Monroe"];
presidents.reverse();

//-> ["Monroe", "Madison", "Jefferson", "Adams", "Washington"]
presidents;
//-> ["Washington", "Adams", "Jefferson", "Madison", "Monroe"];
presidents.reverse(true);
//-> ["Monroe", "Madison", "Jefferson", "Adams", "Washington"]
presidents;
//-> ["Monroe", "Madison", "Jefferson", "Adams", "Washington"]

About the Author

ANDREW DUPONT is a UI developer living and working in Austin, Texas. He is a member of the core development team for Prototype, the popular JavaScript toolkit. He has contributed to Prototype in many different ways: writing code and documentation, offering support, and evangelizing to colleagues. In addition, Andrew has spoken about JavaScript at South by Southwest Interactive and other tech industry conferences.

Andrew received liberal arts and journalism degrees from the University of Texas at Austin. He occasionally attended classes, but much preferred the time between classes, during which he experimented with web design and learned about the emerging web standards movement.

No comments: