« Home | Loading scripts asynchronously. » | Chess rules » | A good recent game that I won. » | Detecting php duplicate and unused code. » | javascript functions. » | Create tunnel via the ssh command in linux. » | Find tables which are empty in database. » | Svn branching strategies. » | Excellent tutorial on linux usermanagement and sud... » | Using Grep to search in files » 

Saturday, November 12, 2011 

Javascript.

OOP:
ECMA 262 standard.
Action script for flash is also based on ECMA standard.
Objects, Classes, Encapsulation, Inheritance, Polymorphism.
Objects - nouns, methods - verbs, properties - adjectives.
Encapsulation - Public, private, protected (information hiding) - In javascript everything is public - but use closures to hide.
Agregation - combining several objects into one.
Inheritance - classes inherit from classes (javascript objects inherits from objects - so objects based on objects)


Polymorphism - ability to calling the same method on two different objects.


Primitive types:
number, string,boolean, undefined, null


Numbers - 0x - hex, 2e+2 - means 200, 23, Infinity - is a special value /number :), NaN (is also a number - if you multiply 10*f  - as f is not a number result is a NaN) max 308 zeros 309 is too much.
Automatic string conversions to number take place if you use *number like string*  in arithematic operators otherwise NaN is r
Note - NaN == NaN - is false


typeof operator in javascript.


You can use array operators to access individual character in a javascript string - var s = 'one';
>>> s[0]
"o"


A better way to check if a variable is defined is to use typeof.
>>> if (typeof somevar !== "undefined"){result = 'yes';}
>>> result;
""
For-in Loops - for arrays
var a = [ 'a', 'b', 'c', 'x', 'y', 'z'];
var result = '\n';
for (var i in a) {
result += 'index: ' + i + ', value: ' + a[i] + '\n';
}


Functions:
arguments is an array which receives the arguments, number of arguments passed / declared does not matter. extra arguments would remain undefined.


callbacks - functions passed as arguments to other functions - typical usage is to delegate the responsibility of calling a function to another function dynamically (say you can write a sort function which takes the comparison function as a call back). They can help with performance esp to avoid multiple for loops etc in few cases.
selfinvoking anonymous functions - usage is esp to avoid name space collisions
private functions - usage is to have functions secured with in a function not available in the global name space.
functions returning functions - this is to access scope see closures later.
functions updating themselves - generally to do some initial setup in the scope and once done, use a normal function.
Ex:
var a = function() {
function someSetup(){
var setup = 'done';
}
function actualWork() {
alert('Worky-worky');
}
someSetup();
return actualWork;
}();


Function scope:
- this (the current object on which it is using  - if no object is used and the function is just called like that it uses window object as this)
- Lexical scope (all the variables with in the scope of this function and its parents - where it is defined (not executed) are accessible via this scope).
- Functions have lexical scope, ie scope is defined when the function is defined. However as soon as the function is called, the scope is used to assign the latest values to the variables used in the function. This is how closures work.


check below two examples to understand how this works.


Example1: Understanding what lexical scope means

>>> function f1(){var a = 1; f2();}
>>> function f2(){return a;}
>>> f1();
a is not defined
Inside the function f1() we call the function f2(). Because the local variable a is also inside f1(), one might expect that f2() will have access to a, but that's not the case. At the time when f2() was defined (as opposed to executed), there was no a in sight. f2(), just like f1(), only has access to its own scope.

Example2: Understanding how variable access from the scope happens when the actual function call is made.

function f() {
var a = [];
var i;
for(i = 0; i < 3; i++) {
a[i] = function(){
return i;
}
}
return a;
}


var a = f();
a[0]();  (output - 3)
a[1]();  (output - 3)
a[2]();  (output - 3)

Lexical scope + variable access during run time in action:


function f() {
var a = [];
var i;
for(i = 0; i < 3; i++) {
a[i] = (function(x){
return function(){
return x;
}
})(i);
}
return a;
}


var a = f();
 a[0]();  (output - 0)
 a[1]();  (output - 1)
 a[2]();  (output - 2)


Objects:
var o = {prop: 1};
var o = {"prop": 1};
var o = {'prop': 1};


property names of objects generally leave with out any quotes, however quotes are necessary if your property name starts with number/ has special chars / is a javascript identifier.


JavaScript uses arrays to represent indexed arrays and objects to represent associative arrays. If you want a hash in JavaScript, you use an object.


Object property values can be accessed using square bracket notation or . (dot) notation.
o.constructor property returns the constructor function
o.toString() is a method that returns a string representation of the object
o.valueOf() returns a single-value representation of the object, often this is the object itself


Constructor functions:
function Hero(name) {
this.name = name;
this.occupation = 'Ninja';
this.whoAreYou = function() {
return "I'm " + this.name + " and I'm a " + this.occupation;
}
}


var h1 = new Hero('Michelangelo');
var h2 = new Hero('Donatello');
h1.whoAreYou();


(output - "I'm Michelangelo and I'm a Ninja")


By convention, you should capitalize the first letter of your constructor functions so that you have a visual clue that this is not a normal function.


function Hero(){}
var h = new Hero();
var o = {};
>>> h instanceof Hero;
output - true
>>> h instanceof Object;
false
>>> o instanceof Object;
true




Functions that return objects 


function factory(name) {
return {
name: name
};
}


var o = factory('one');
>>> o.name
one
however o.constructor() would return Object.


Objects are always assigned / passed by reference. See the below examples.


var original = {howmany: 1};
var copy = original;
>>> copy.howmany   (output: 1)
copy.howmany = 100;
>>> original.howmany (output: 100)




Built in objects:
Data wrapper objects—Object, Array, Function, Boolean, Number, and String.
Utility objects—These are Math, Date, RegExp
Error Object - Error


Array object:
var a = new Array(1,2,3)
>> a
[1,2,3]
var b = new Array(2);
>>b
[undefined, undefined]


Array has length property which on modifying dynamically changes the length of the array.
slice(), splice() functions give us a chunk of the array between offsets, however splice along with giving the slice modifies the original array by removing the slice it has returned.


Function objects:
 var sum = new Function('a', 'b', 'return a + b;');
creates a function sum similar to  function sum(a,b){return a+b;} however using the function constructor is not good just as eval.
Function objects have the following properties
- length - return the number of arguments it accepts.
- caller - returns the function that has actually called this function. If you call a function from global space caller would be null.
- prototype - property of a function contains an object. This is the object that is used to create new objects when this function is used as constructor. All objects created with this function keep a reference to the prototype property and can use its properties as their own.


Methods on function objects:
- toString - To string would return the function code in string format.
- call - used to call a method on a particular object on another object.
- apply - same as call but arguments are passed as array.


some_obj.someMethod.apply(my_obj, ['a', 'b', 'c']);
some_obj.someMethod.call(my_obj, 'a', 'b', 'c');




The arguments variable with in a function looks like an array however it only has the length property of array. If you want to use some other methods of array on this use the apply method on those array methods.


The arguments object has a callee property which would have a reference to the function itself so you can do something like anonymous functions recursively calling themselves.


(
function(count){
if (count < 5) {
alert(count);
arguments.callee(++count);
}
}
)(1)


Number object.
Number.MAX_VALUE will return the max value of that you can store in the number.
toFixed - method returns the number to the significant decimal digits.


var n = new Number(123.456)
>>> n.toFixed(1)
"123.5"


Simillar to Boolean(), the Number() function can be used as normal functions in order to try to convert any value to a number. This is similar to the use of parseInt() or parseFloat(). OR As a constructor function (with new) to create objects


var n = Number('12.12');
>>> n
12.12
>>> typeof n
"number"
var n = new Number('12.12');
>>> typeof n
"object"


- Note that this is not the case with Function object, it with either new / with out it would create a function.
var c = Function('a','return a;');
or
var f = new Function('a','return a;');


>>>typeof c
function
>>>typeof f
function


Delete variables in javascript:

Here is an excellent article from perfection kills on delete. The final gyst below
  • Variables and function declarations are properties of either Activation or Global objects.
  • Properties have attributes, one of which — DontDelete — is responsible for whether a property can be deleted.
  • Variable and function declarations in Global and Function code always create properties with DontDelete.
  • Function arguments are also properties of Activation object and are created with DontDelete.
  • Variable and function declarations in Eval code always create properties without DontDelete.
  • New properties are always created with empty attributes (and so without DontDelete).
  • Host objects are allowed to react to deletion however they want.

Javascript How functions / objects / Prototype / Constructor work.


  • When you define a function in javascript, it by default would have a prototype property set.
  • This prototype is an reference object which has - constructor property which is a reference to the function itself and any other methods added to it explicitly and few other internal methods.
  • When you create a object from a function (lets call it constructor function), using the new keyword, the following things happen.
    • An empty object is created, its internal __proto__ property is set to refer to same object that prototype of the constructor function (which is used to create it) is referring to.
    • Then the Constructor function is called with the "this" of that it pointing to the newly created object.
    • The Constructor then returns what ever value it has in return statement / the this object if nothing is returned.
  • The above process helps in getting the inheritance going.
  • Good thing is that you can extend the prototype object of the constructor function and it would add that extension to all the objects that are so far created with this constructor.
Javascript OOP:
  • Prototypal Inheritance: object.create()
Object.create() is automatically present in new browsers. For old browsers, use the following.
// helper function
if (typeof Object.create !== 'function') {
  Object.create = function (o) {
    function F() {}
    F.prototype = o;
    return new F();
  };
}

var person = {
  sayHello : function () {
     alert('Person object');
  },
  walk : function () {
    alert('walk');
  }
};
var student1 = Object.create(person);
student1.sayHello = function () {
  alert('hello I am a student');
};
Adv: We dont call the super class constructor function, just copy the prototype of it onto a empty function and then copy it onto our object.
Objects inherit from objects.
Dis: This itself becomes a dis when you specifically want to call the super class constructor which might set some instance properties. 
You can manually call the constructors, chaining them.
  • Psuedo classical Inheritance: achieved like this. Difference between protoypal and classical as I observe is in prototypal, you just create an new object from old object. But in psuedo classical style, you create a inherits method on top of the constructor function of new object and point the prototype property of the constructor function of new object to the inherted object.
or instead of inherits you can also simply have.
// define the Person constructor function
function Person() {}
Person.prototype.sayHello = function(){
  alert ('hello');
};
// define the Student constructor function
function Student() {}
// inherit from Person
Student.prototype = new Person();
// correct the constructor pointer because it points to Person
Student.prototype.constructor = Student;
// replace the sayHello method (a polymorphism example)
Student.prototype.sayHello = function () {
  alert('hi, I am a student');
}
var student1 = new Student();
student1.sayHello(); 
Adv: Super class constructor is called everytime so instance properties if any could be set.
Dis: If all you need is prototype properties than calling the constructor is a overhead.
  • Parasitic inheritance: In the "derived" constructor you create a "base" object instance, that object is augmented and that new instance is returned:
// Person constructor function
function Person(name) {
  this.name = name;
}
function Student(value) {
  var that = new Person(value);
  that.sayHello = function () {
    alert('hello I am a student');
  };
  return that;
}


How to do
  • Public, Private, Privileged methods / variables.
http://phrogz.net/js/classes/OOPinJS.html

  • private variables are declared with the 'var' keyword inside the object, and can only be accessed by private functions and privileged methods.
  • private functions are declared inline inside the object's constructor (or alternatively may be defined via var functionName=function(){...}) and may only be called by privileged methods (including the object's constructor).
  • privileged methods are declared with this.methodName=function(){...} and may invoked by code external to the object.
  • public properties are declared with this.variableName and may be read/written from outside the object.
  • public methods are defined by Classname.prototype.methodName = function(){...} and may be called from outside the object.
  • prototype properties are defined by Classname.prototype.propertyName = someValue
  • static properties are defined by Classname.propertyName = someValue

Currying:
If the arguments passed to a function are less than it expects, it can return a partial curry function, to which we can pass the missing arguments and get the actual result later as if we were called the original function with all the arguments.



function curry(func) {
var args= arguments.slice(1);
return function () {
return func.apply(null,
args.concat(arguments.slice()));
};
}
var inc = curry(function add(a, b) {
return a + b;
}, 1);
alert(inc(6)); // 7


when you find yourself calling the same function and mostly passing the same parameters, create a curry with redundant parameters



jslitmus - for performance testing.
closurecompiler - for optimizing js code.