Category Archives: javascript

Javascript is an object-oriented language (1) – Encapsulation

Javascript is a powerful tool. No web developer can live without it. Without Javascript, the webs will be much poorer, as most of user-experience enhancement don’t exist.

Powerful tools are often misused. Javascript is in the same fate. Easy to write, easy to mess. And it soon earn the dispute as one of the most messy language. But investigating further, Javascript is one of the most mis-understood language.

Javascript is an object-oriented language.

That maybe a suprise to some people, and so do I. You see, javascript is often written in one big files, with the statement lined up from start to end… Global variables, C-like syntax,… it just seem to be a typical procedural language.

In fact, Javascript is heavily object-based. Everything in javascript is viewed as an object. Function is an object. Array is an object. But surely, “just because a language has objects doesn’t make it OO.”

You may say: but every property in a Javascript object is public? Aren’t we told that a language can only be called object-oriented when it has “encapsulation“, “inheritance” & “polymorphism“?

For the first question, I can confirm: yes. All property in a Javascript object is public. But Javascript is still an object-oriented-able language. Following I will show you how:

1. Encapsulation

Encapsulation can be achieved by a special feature of Javascript: the closure. Simply put, that’s the ability which allow the inner function has access to local variables in the outer function. A simple piece of code should says more than I could:

var Merlin = function() {
var say = function() { alert(advice); }

// Local variable that ends up within closure
var advice = 'One must complete what he started';
return {say: say};
}

var apprentice = new Merlin();
apprentice.say(); // alert 'One must complete what he started'
alert("Let's look inside of Merlin: " + advice); // alert nothing, since advice is not a global object

To be fully understand the concept of closure, one should study about how Javascript define scope for its object. In the above example, you can easily see that, the function say() can still access the local variable “advice”, even after function Merlin() has completed. Other languages (Java, C, for example) often requires the local variable disposed as soon as the function is complete. This is a strange mind-set, but as you see, it do the “hiding” job just well.

(to be continued)

P/s: Thanks to Mr. An to give his time explaining this to me, which most of the books never make a comment.

A quick experiment on HTML5 Canvas

Photobucket

/** Vietnamese: một thử nghiệm nhỏ lên trang canvas của HTML5 **/

HTML5 is out for a while, and many people have already play with it. Inspired by the great article here, I managed to make a simple dirty experiment.


<!DOCTYPE html>

<html lang="en">

  <head>

    <title>Good night</title>

  </head>

  <body><script type="text/javascript">
  if ( !window.requestAnimationFrame ) {

    window.requestAnimationFrame = ( function() {

      return window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

        window.setTimeout( callback, 800 / 60 );

      };

    } )();

  }
</script><script type="text/javascript">
var canvas, context;
var xx = new Array();
var yy = new Array();
for (var i = 0; 40 > i; i++) {
   xx[i] = Math.random()*600;
   yy[i] = Math.random()*150;
}

init();
animate();
function init() {
  canvas = document.createElement( 'canvas' );
  canvas.width = 600;
  canvas.height = 400;
  context = canvas.getContext( '2d' );
  document.body.appendChild( canvas );
}
  
function animate() {
  requestAnimationFrame( animate );
  draw();
}
function draw() {
  var time = new Date().getTime() * 0.001;
  var x = Math.cos( time ) * 250 + 300;
  var y = Math.sin( time ) * 250 + 300;
  
  if(150 >= y) {context.fillStyle = 'rgb(250,250,250)';}
  else {
    if (200 >= y) {
      context.fillStyle='rgb(200,200,200)';
    } else {
      context.fillStyle='rgb(14, 14, 14)';
    }
  }
  
  context.fillRect( 0, 0, 600, 400 );
    
  context.fillStyle = 'rgb(255,255,0)';

  context.beginPath();
  
  context.arc( x, y, 15, 0, Math.PI * 2, false );
  context.closePath();
  context.fill();
  
  context.fillStyle = 'rgb(0,0,255)';
  context.fillRect(0, 215, 600, 400);
  
   for (var i = 0; 15 > i; i++) {
      
      context.fillStyle = 'rgb(255,255,255)';
      context.beginPath();
      context.arc(xx[i], yy[i], 1, 0, Math.PI * 2, false );
      context.closePath();
      context.fill();
  
      if (y > 200) {
          if (Math.floor(time) % 2 == 0) {
            context.fillStyle = 'rgb(255,255,255)';
            context.beginPath();
            context.arc(xx[i], yy[i] + 215, 1, 0, Math.PI * 2, false );
            context.closePath();
            context.fill();
          } else {
            context.fillStyle = 'rgb(255,255,255)';
            context.beginPath();
            context.arc((yy[i] / 150) * 600, (xx[i] / 600)*150 + 215, 1, 0, Math.PI * 2, false );
            context.closePath();
            context.fill();
          }
        }
      } 
    }
    </script>
  </body>
</html>

You can view the example online here.

Free ads: thanks for the start-up Handcraft for letting me quickly “craft” this product.