Immediately-Invoked Function Expression (IIFE)

Scope in Javascript is function-bound, meaning variables defined in a function are visible inside the same function, and each time a function is invoked it creates a new execution context. This is different from C which confines life span of variables inside a block. For following code:

var a = 1;

function f1() {
  var b = 2;
  console.log('inside f1 a:'+a);
}

function f2() {
  var c = 3;
  return function(d) {
    return d+c;
  }
}

{
var e = 5;
}

f1();

console.log(a);
console.log(b); //error
console.log(e);
console.log(f2()(4)); //closure

Only hidden variable to the global context is b. Since every C function is defined using block Javascript is more loose in the sense that blocks without function declaration doesn’t really do much.

Now move on to Immediately-Invoked Function Expression: the motive behind this is you want to execute a piece of code without contaminating the global context while being able to use many of the global variables. You do it by creating an anonymous function and immediately invoking it:

(function () {
 ...
})();

This is a very common pattern for Javascript and is seen everywhere, especially for locking in the value of
execution context. More reading can be found at http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Obtaining user’s zipcode with in browser

HTML5 offers the capability of obtaining browser’s physical location via it’s geolocation API:

https://developer.mozilla.org/en-US/docs/WebAPI/Using_geolocation

The result consists of latitude and longitude. This is good, especially when you are making a Maps app. But sometimes the use case/database behind is organized by address/town/zipcode rather than geolocations, and we would like to convert the geo result to zipcode for example. We can achieve this by calling Google Maps API:

https://developers.google.com/maps/documentation/javascript/reference#Geocoder

What returns from this API call has an array of possibilities and usually the first one is good enough. Some sample code below:

function getLocation() {
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(function(pos){
            var g = new google.maps.Geocoder();
            var latlng = new google.maps.LatLng(pos.coords.latitude, pos.coords.longitude);;
            g.geocode ({'location':latlng}, function(results, status) {
              if(status === google.maps.GeocoderStatus.OK) {
                if (results[0]) {
                  for(var i=0; i<results[0].address_components.length; i++){
                      var types = results[0].address_components[i].types;
                      if(types[0]==='postal_code') {
                        var postalCode = results[0].address_components[i].long_name;
                        console.log(postalCode);
                      }
                  }
               }
              }
            });
          });
        } else {
          console.log("Geolocation is not supported by this browser.");
        }
      }

EMFILE error in node.js

This usually happens when we asynchronously operate on a large number of files in Node.js and due to the async nature of Node.js many files are open at the same time. See explanation at https://stackoverflow.com/questions/16200497/emfile-error-in-async-file-reading

Two solutions: 1) use sync version of readFile. so each file is closed before proceeding to next 2) use callback function for reading next file, something like


function readFile(files, i) {
  if(i>=files.length) return;
  fs.readFile(path+'/'+files[i], 'utf8', function (err,data) {
    if (err) {
      return console.log(err);
    }
    parse(data, function(result){
      readFile(files,i+1);
    });
  });
}

fs.readdir(path, function(err, files) {
  readFile(files,0);
});

How to define classes in Javascript

Strictly speaking, there’s no class in Javascript. To create objects of class, there are a few options:

1. Directly define an object as well as its vars/methods.  You cant create its instances in this case.

var foo = {
 x: [1,2,3],
 y: function(name) {
   return 'hello '+name;
 }
}

console.log(foo.x); //OK
console.log(foo.y('john')); //OK

var foo2 = new foo();//wrong: object is not a function

operator new has to be used on a function.

2. Define a function as well as its vars/methods. Create instance through new. For the vars there are two options:
2.1 vars are public members through “this.”.

var foo = function(name) {
  this.x = [1,2,3];
  this.y = function() {
    return 'hello '+name;
  }
}

console.log(foo.x);//undefined
console.log(foo.y());//no such method

var foo2 = new foo('john');

console.log(foo2.x);
console.log(foo2.y());

2.2 vars are private by not using this

var foo = function(name) {
  var x = [1,2,3];
  this.y = function() {
    return 'hello '+name;
  }
  this.getX = function() {
    return x;
  }
}

//console.log(foo.x);//undefined
//console.log(foo.y());//no such method

var foo2 = new foo('john');

console.log(foo2.x);//undefined. x becomes private
console.log(foo2.y());
console.log(foo2.getX());

3. Define a function. Vars/methods are added through prototype.. Create instance through new. This way instances all share the same method space improve runtime efficiency.

prototype, constructor function, etc. in Javascript

Javascript is a loose-typed language and sometimes it can be very confusing. I wrote some quick code as below. In conclusion:

  • constructor functions are like classes in other languages
  • prototype only changes objects through operator ‘new’. so any methods attached through prototype can only be invoked from objects. also they are shared across different objects (just like other languages).
  • there’s a way to define “class” methods as well: defined directly on the constructor function. this is like a public static method to other languages

some helpful urls

http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/

http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work

function f() {
this.greeting='hello';
myname:'fooname'
}
f.var1 = 'world';
f.method1 = function() {
console.log('hello from method1');
}

var foo = new f();

console.log('f.myname:'+f.myname); //undefined
console.log('foo.myname:'+foo.myname);//undefined</pre>
console.log('f.var1:'+f.var1); //world
console.log('foo.var1:'+foo.var1);//undefined
console.log('f.greeting:'+f.greeting);//undefined
console.log('foo.greeting:'+foo.greeting);//hello

console.log('f.prototype:'+f.prototype);//object
console.log('foo.prototype:'+foo.prototype);//undefined
console.log('foo.__proto__:'+foo.__proto__);//undefined

f.prototype.age=13;
console.log('f.age:'+f.age);//undefined
console.log('foo.age:'+foo.age);//13

f.method1(); //hello from method1
// foo.method1(); TypeError: Object #&lt;f&gt; has no method 'method1'

var car = {
myname:'i am a car'
}

var ford = {
kind:'i am a ford'
}

console.log('ford.myname:'+ford.myname);//undefined
ford.__proto__ = car;
console.log('ford.myname:'+ford.myname);//i am a car