Wednesday, April 1, 2015

JavaScript tricks

Duck typing

You can invoke an object's method on another object, as long as the latter has everything the method needs to operate properly. Example:
function foo() {
  // the last element of arguments is popped
  Array.prototype.forEach.pop.bind(arguments)();
  // this works as if arguments had a "forEach" method
  Array.prototype.forEach.bind(arguments)(function(a){ console.log(a) }); 
}

Dynamic scoping

The easiest way to archive dynamic scoping in JavaScript is to use eval:
var x = 1;
function g() {
  console.log(x);
  x = 2;
}
function f() {
  // create a new local copy of `g` bound to the current scope
  var x = 3;
  eval(String(g));
  g();
}
f();             // prints 3
console.log(x);  // prints 1
Perhaps this is one of the few valid reasons to use eval in JavaScript.

Loose augmentation

Suppose that you have several module files that share a MODULE variable. Then it is preferable to let organize each module file like
var MODULE = MODULE || {}; // MODULE is always declared due to hoisting
(function() { 
  var private_var;         // only accessible to myFunction
  MODULE.myFunction = ...  // augment the module with a new function 
})();
In this way, you can load all of your module files asynchronously without the need to block, given that the functions defined in the module don't depend on each other.

Call-site memorization

The word memoization refers to function-level caching for repeating values. Suppose we have a function G such that G(f) will compute an expensive function f many times. If f is pure, then we can cache the results of f without modifying G or introducing global variables. Instead of calling G(f) directly, we pass to G a closure of f as follows:
var memorize = function(f) {
  var cache = {};
  return function(x) {
    if(!cache.hasOwnProperty(x))
      cache[x] = f(x);
    return cache[x];
  };
};
G(memorize(f));
The use of cache here is totally transparent from the view of G. Note: You may want to use an LRU/LFU cache to avoid running out of memory.