Pages

Friday, July 6, 2012

Javascript Tips

Running, Testing & Debugging your JS
I use Google Chrome for my JS development. Click "Tools > JS Console" and you can put break points, trace, watch variables and see the log/error messages that your JS produces. Chrome allows you to print your own logs to it's console through a 'console' object which is internally defined, I used to use 'alert()' function which was a pain;
 console.log("we are here");  
Variables & Scopes
If you use the 'var' keyword a new variable will be created in the current scope. If you just do a variable assignment JS will start searching the variable starting from the current scope to upper (caller) scopes. If it finds the variable it won't create a new variable and assign the value to that variable. If it can't find any previously declared variable it will create a variable in the top level (global) scope.
Here is an example;
 for(i = 1; i <= 3; i++) {  
      print()  
 }  
 function print() {  
      for(i = 1; i <= 3; i++) {  
           console.log(i);  
      }  
 }  
Here I am using 'i', as I usually I do on my 'for' loops, but the 'i' variable is actually created only once on the top scope. Once the 'print' loop is done upper loop also exits, so 1, 2, 3 is logged only once.  If we append a 'var' to 'i' on the first loop nothing will change. If we append a 'var' on  to 'ion the second loop there will be two different 'i' variables on different scopes hence the 1, 2, 3 will be printed 3 times.
So if you are looking for "C like" scope behavior best you could do is not forgetting to use the 'var' keyword.
Declaring Classes & Methods
You can do object oriented programming in JS. Here is an Object constructor:
 function Matrix(ray, rlen, clen) {  
   this.ray = ray;  
   this.rlen = rlen;  
   this.clen = clen;  
 }  
 Matrix m = new Matrix([],2,2);  
 console.log(m.rlen)  
whit the 'this' reference we are assigning parameter values to object fields and than we can reference them through the '.' operator.
To create methods for our 'Matrix' object and call them:
 Mx.prototype.findMin = function () {  
 // code to find the min  
 ...  
   return min;  
 }  
 m.findMin()  
You can use the 'this' to reference the fields, from methods. These are the very basics I mostly use. There is also support for inheritance, private fields etc. but I found the notation a bit complicated.
Anonymous Objects or Structs
A nice feature used is creating sort of an anonymous objects (I think these are more like structs in C);
 var user = {  
     name: "mca",  
     numOfLogins: 10,  
     roles: []  
 };  
Here we can use the '.' operator to access the fields as usual. Also JS uses '[]' to denote arrays which has methods like 'pop', 'push' etc.
Closures
One last thing is that JS has some nice support for functional programming;
 var f = function(n) {  
      var r = 1;  
      for(var i = 2; i <= n; i++) {  
           r *= i;  
      }  
      return r;  
 }  
 alert(f(3));  
 var f3lazy = function (g,n) {  
      return (function(g,n){  
                return function() {return g(n)};  
           })(g,n);  
 }(f,3);  
 alert(f3lazy);  
 alert(f3lazy());  
Variable 'f' is assigned with a factorial function. We could use it as a parameter to other functions or just call it like it's done with 'alert(f(3))'.
Below that is something you could do which is more tricky. Variable 'f3lazy' is assigned to a function which will call the factorial function with parameter '3' when called with no parameters. It's an example of how you could create lazy functions through functions already there.