Friday 11 June 2010

Some JavaScript Magic

It's not a secret that I consider JavaScript one terribly interesting language. I quite like its Prototype based object orientation and how its enormous flexibility allows us to simulate class orientation. I've got a certain amount of experience with JavaScript and I'm sort of a Language freak (I don't know a word about compilers-interpreters programming, but I'm very much interested in the different features and idioms provided by different languages), but anyway JavaScript continues to wonder me with new pieces of wisdom.
So, I'm going to talk of some of the last ones I've found (or rediscovered) lately:

  • JavaScript closures are one of its more important features. It's very interesting to learn how the [[scope]], execution context, scope chain... work together. Yesterday I found a use of closures that I'd never seen before and really amazed me, using closures for anonymous recursive functions:

    var count = function countToTen(i) {
    if (i <= 10) {
    console.log(i);
    count(i+1); // Call count with the power of closures
    }
    }
    when countToTen is declared, it's [[scope]] property traps the count variable, so when countToTen is executed, it can find count in its execution context.
    as the article says, you no longer need arguments.callee nor named functions (thought anyway, for debugging purposes I think all functions should be de-anonymized)

  • Functions with return values being used as constructors. This is rather interesting. In most languages I know constructors do not return any value. In JavaScript, the concept of constructor not rigid at all, in fact, I think we can say that we don't have constructors, we just have functions, and when a function is called following a new statement it works as a constructor.

    var p1 = new person();

    I think it works this way: new creates a new object, the object gets its constructor [[Prototype]] property pointed to person() and then is passed to person() as this. person does whatever it wants with this and if it does not have a return statement, the new object-this is assigned to p1. Nothing unusual so far. But, what happens if person has a return statement? in that case it's the object returned by the function what gets assigned to p1. This, apart from being a rather freak feature, could not seem way too useful, but for example it could be useful for implementing a singleton pattern this way.
    What I like of that implementation is that the singleton no longer looks like a singleton to the outside world when referencing it. What I mean with this is that instead of the classic singleton.instance... we can call new as many times as we want, and we'll be receiving the same object...
    It's as if the class was no longer expressing in its contract that it's a singleton, is this really a good idea?
    Also, this thing reminds me of __new__ in Python, that is sometimes (ab)used to implement sort of a factory.

  • I really like when something makes you scratch your head, even if it's not especially useful. First time I saw somewhere a JavaScript line like this:
    this();
    it really caught me by surprise.
    Well, it's not that strange (taking into account that functions are objects and as such can be "expanded"), if "this" can be invoked it means "this" points to a function, so if we think how the "this" gets assigned, an example would be just something like this:

    var f1= function(){print("I'm f1");};
    f1.hi = function(){this();};
    f1.hi();

    Thinking around this a bit more it came to my mind how we could write a rather confusing line. Let's say we have a person "class" and we're going to add some "static" methods to it:

    function person()
    { this.name=....};
    //instance methods
    person.prototype.dump = function(){...};
    //static methods
    person.static1 = function(){...};
    //this looks rather confusing, cause having a "this" in a "static" does not seem too natural
    person.static2 = function(){this.static1();}
    //this one looks much more natural way to call a static method
    person.static3 = function(){person.static1();}

  • While checking some more JavaScript code in the web I came across this lazy function definition pattern. It's both simple and interesting. A problem with this is that we're just changing where the reference points to. If we had more than 1 reference to the function object, it would only work for one of them. It would be beautiful if we could replace the code inside the function itself, something like:
    arguments.callee.code = function(){...}.code;
    it would just involve that functions had a code property containing their code itself.

No comments:

Post a Comment