Posted: February 10th, 2010 | Author: diegoquinteiro | Filed under: Uncategorized | No Comments »
Encapsulation is the most important achievement of object oriented programming. Using a piece of software without worrying about its implementation makes possible for our limited brain to understand and code complex applications.
A simple example in Java:
public class Point {
private double x;
private double y;
public Ponto (double x, double y) {
this.x = x;
this.y = y;
}
public double distanceFromOrigin () {
return Math.sqrt(x * x + y * y);
}
}
Anyone who wants to use this class doesn’t need to know how the point coordinates is stored or how the distance from the origin is calculated. The information is encapsulated. Encapsulation improves abstraction and simplifies our code.
In order to encapsulate properly, we need private members, i.e. variables that can’t be read or changed from outside our software piece.
In more traditional languages such as Java, it is done with explicit access control. By using the private keyword, we prevent the variable from being accessed outside its own class. But how can we do the same with JavaScript, since it doesn’t even have classes?
In fact, it’s very simple. Variables defined within a function are confined to the function scope. As discussed in my last post about closures, inner functions have access to their outer function’s scope. Putting it all together, we have what we want:
var Point = function (x, y) {
this.distanceFromOrigin = function () {
return Math.sqrt(x * x + y * y);
}
}
var point = new Point(3, 4);
alert(point.distanceFromOrigin()); // alerts "5"
alert(point.x); // alerts "undefined"
alert(point.y); // alerts "undefined"
That way, x and y are private members. They are local variables of the constructor and would not exist outside it. When distanceFromOrigin is assigned to the this object, which is returned, a closure is created so that function will keep permanent access to that local variables.
The cost of using this technique is that with every execution of the constructor the inner functions are recreated. One instance of each method for each object instance. Usually this is not a problem at all, but watch out for objects that have hundreads or thousands of instances.
Posted: January 30th, 2010 | Author: diegoquinteiro | Filed under: Uncategorized | Tags: javascript, object oriented programming | 3 Comments »
Get to know the scope of your variables. In JavaScript only functions can define scopes and only variables explicit declared by using the var keyword are restricted to local scopes, otherwise they’re global. Furthermore, function parameters are also local variables. Pay attention to this example:
function example (arg) {
var localVariable = 0;
if (arg > 0) {
var sameScope = arg + 1;
}
localVariable = sameScope;
alert(localVariable);
globalVariable = arg;
}
example(1); // Alerts "2"
alert(localVariable); // Alerts "undefined"
alert(sameScopo); // Alerts "undefined"
alert(globalVariable); // Alerta "1"
Notice that the sameScope variable could be assinged to localVariable althought it was declared inside an if block. Blocks doesn’t define scopes, only functions do.
JavaScript always defines a global object, which in the browsers is the window object. All global variables are in fact properties of this object, so:
example(0);
window.example(1); // functions are also variables
alert(globalVariable); // Alerts "1"
alert(window.globalVariable); // Alerts "1" too
alert(globalVariable === window.globalVariable); // Alerts "true"
Closures
Functions in JavaScript are first-class objects. That means you can pass a function to other functions, assign functions to variables or use them as return value. A declaration function functionName (arg1, arg2, …) { … body … } have the same effect as var functionName = function (arg1, arg2, …) { … body … };.
The inner functions always have access to the outer function’s variables. For example:
var outerFunction = function (value) {
var outerFunctionVariable = value;
var innerFunction = function () {
alert(outerFunctionVariable);
}
innerFunction();
}
outerFunction(1); // Alerts "1";
Something curious happens when we keep a reference to the inner function after the outer function execution:
var outerFunction = function (value) {
var outerFunctionVariable = value;
var innerFunction = function () {
alert(outerFunctionVariable);
}
return innerFunction;
}
var inner1 = outerFunction(1);
var inner2 = outerFunction(2);
inner1(); // Alerts "1"!
inner2(); // Alerts "2"!
That way we created a closure.
Local variables created by the outer function weren’t destroyed even after its execution. By keeping a reference to innerFunction, we also prevented the outerFunction variables to die.
This is a powerful feature of the language, as we will see in next posts.
Posted: January 30th, 2010 | Author: diegoquinteiro | Filed under: javascript | Tags: javascript, object oriented programming | 5 Comments »
Fact: JavaScript is an object-oriented language.
So you can ask: where are the damn classes?
The truth is that there are no classes. JavaScript objects are soft: one can freely add, modify or remove properties from each of them individually in runtime. It’s a diferent way of programming object oriented, and a very powerful way.
The new operator
To master object orientation in JavaScript you need to clearly understand the new operator behaviour. This operators is used to create and initialize a new object given a function, called “constructor function”. For example:
function Person(name) {
this.name = name;
}
var diego = new Person("Diego");
alert(diego.name); // Alerts "Diego"
var gabriel = new Person("Gabriel");
alert(gabriel.name); // Alerts "Gabriel"
Notice that diego and gabriel are not instances of Person class. Indeed, there’s no Person class, just a function named Person. Remember: there are no classes in JavaScript
When the new operator is used, an empty object is created and passed to the constructor function as the this reference. The function then can add members to that object by simple assignment, as in this.name = name.
Unless the function returns a not null object, the object this is returned and a reference for the constructor function is stored in the constructor property.
The result is very similar to class instantiation and we are tempted to call Person a class. It would be a real class if the object couldn’t be modified after its creation. JavaScript doesn’t works that way: objects can have properties and methods removed or modified anytime after their construction.
For didactic purpose, we’ll now implement the JavaScript new operator as a function:
var operatorNew = function (constructorFunction, args) {
var object = {}, // creates an empty object
returnValue;
// calls the function passing the object as 'this'.
returnValue = constructorFunction.apply(object, args);
if ((typeof(returnValue) !== "object" &&
typeof(returnValue) !== "function") ||
returnValue === null) {
// if returnValue is not a not-null object returns 'this'
returnValue = object;
returnValue.constructor = constructorFunction;
}
return returnValue;
}
So the call…
var object = new ConstructorFunction(arg1, arg2, ...);
… will be the same as
var object = operatorNew(ConstructorFunction, [arg1, arg2, ..]);
… for any ConstructorFunction implemented in JavaScript.
PS: It won’t work with primitive types (String, Array etc). These are implemented in the browser, not in JavaScript code.
Analysing the operatorNew function we created, we realize that the new operator is just a shortcut. We can always create objects from literal notation then add members freely using no constructor at all.
Look at the following code:
var diego1 = new Person("Diego");
var diego2 = {}
diego2.name = "Diego";
diego2.constructor = Person;
var diego3 = {constructor: Person, name: "Diego"};
var diego4 = operatorNew(Person, ["Diego"]);
The objects diego1, diego2, diego3 and diego4 are equal!
Make no mistake: objects and construtors are in, classes are out.
That’s the JavaScript way.
Posted: July 2nd, 2008 | Author: diegoquinteiro | Filed under: Sem Categoria, methodology | Tags: getting real, methodology, ruby on rails | 5 Comments »
The messages from Getting Real book are quite unusual. Some of the concepts defended by the 37signals gurus, the creators of Ruby on Rails, seems to go against everything we learned:
- Get real!
- Toss your crystal ball: don’t wast your today solving tomorrow’s issues – you have enough problems to worry about today.
- Your working project must be your best if not only documentation. Don’t create documents that never come true.
- Avoid meetings. When they are absolutely necessary, set your mobile alarm to 30 minutes: when it rings, meeting is over.
- Keep in mind that errors will occur. Don’t worry: it’s a web system, not a cerebral surgery.
It’s a very shocking approach that some may disagree, but it’s surely valuable to all.
The full text is available for free, take a look.