Nerdworks logo "The nerd shall inherit the earth."

Nerdworks Blogorama

Nerdspeak

Web Cast on Web Workers
Technobabble
7/21/2011 4:51:42 AM  

I did a web cast today on developing web apps with web workers. Hope you folks found it useful. The recording should hopefully be available online soon. In the meantime you can download the deck and the demos from here:

https://skydrive.live.com/?cid=2C5064CB54B16F50&id=2C5064CB54B16F50%21314&sc=documents

Do feel free to leave any questions you might have as a comment on this post or email me or message me on twitter and I’ll be happy to answer them. I also have a plan to make a post talking about some of the interesting bits of the “FilterMe” demo that I showed on the session (also available for download at the link given above) today, but whether that actually transpires or not remains to be seen! Smile with tongue out

Link Comment (1)
 
Using closures as backing fields for ECMAScript5 properties
Technobabble
7/12/2011 11:28:08 AM  

One of the things that ECMAScript version 5 brings to the JavaScript world is the ability to define “getter” and “setter” properties, i.e., the ability to define object members that look like regular fields to clients but are really member methods. The best way to understand this is with an example. Here goes:

var person = Object.create({}, {
    name: {
        get: function() {
            print("name.get");
            return "foo";
        },
        set: function(v) {
            print("name.set - " + v);
        },
        enumerable: true,
        configurable: false
    }
});

person.name = "boo";  // calls the "set" function above
print(person.name);   // calls the "get" function above

We’ve defined an object called “person” above with one property called “name”. We’ve defined “get” and “set” functions which will cause the JavaScript runtime to call the respective methods whenever an attempt is made to access the property or set a value for it. This works exactly the same way as how properties work in C#. If you run the snippet given above here’s the output we get:

name.set - boo
name.get
foo

You’ll note that I really haven’t actually saved the value being passed as a parameter to the “set” function of the “name” property above. In a real program you’d typically want to save this in a backing field of some sort. Now, the question is, where do we save this? One approach could be to do something like the following:

var person = Object.create({}, {
    nameVal: {
        value: null,
        enumerable: false,
        writable: true,
        configurable: false
    },

    name: {
        get: function() {
            return this.nameVal;
        },
        set: function(v) {
            this.nameVal = v;
        },
        enumerable: true,
        configurable: false
    }
});

person.name = "boo";
print(person.name);

While this works, it does however defeat the purpose of defining separate getter and setter methods since the client of this object is anyway able to directly write to “nameVal”. We need a mechanism of somehow hiding the backing field so that it is accessible only from the getter/setter methods and not through an object instance.

Enter closures! It turns out that the descriptors for a property can actually be defined dynamically at runtime. It can be for instance, be returned from a function. We should be able to leverage this to define a self-calling function that results in the creation of a separate execution scope where the backing field for the property can be stored as a part of the closure for the scope. Again, an example should make the idea clear.

var person = Object.create({}, {
    name: (function() {
        var nv = ""; // backing store in closure

        //
        // the property descriptor is actually
        // returned from this function
        //
        return {
            get: function() {
                print("name.get");
                return nv;
            },
            set: function(v) {
                print("name.set");
                nv = v;
            },
            enumerable: true,
            configurable: false
        };
    })()
});

person.name = "foo";
print(person.name);

This snippet is identical to the first example except that the property descriptor for “name” is being returned from an anonymous self-calling function. The backing store for the property is stored in a variable that becomes a part of the closure for the setter and the getter methods. This achieves our goal of creating a backing field that is accessible only from the getter/setter routines.

The dynamism of JavaScript can get a bit unwieldy sometimes but this is one occasion where being able to dynamically generate the property descriptor ends up providing an elegant solution to the problem of creating backing stores for member properties!

Link Comment
 
Calling the "base" with prototypal inheritance in JavaScript
Technobabble
7/11/2011 11:09:34 AM  

I wrote a little bit about how inheritance was designed to work in JavaScript sometime back. Briefly, inheritance in JavaScript is “prototypal” in nature and instead of types inheriting from other types, we have object instances inheriting from other object instances. Being a weakly typed language, the traditional interpretation of inheritance as it applies to a static strongly typed language does not apply here. Each object in JavaScript has a hidden reference to another object called its “prototype”. Member references (i.e. when you access a property like so: obj.prop) are resolved by the runtime by first looking the object itself up for the member and if not found then looking for it in the object’s prototype. If the member is still not found then the prototype’s prototype is inspected and so forth till the prototype of the root Object object is encountered at which point the member is declared as non-existent. The blog post I linked to earlier talks about this in detail.

I am working on a project where I have an inheritance hierarchy such as the following:

var Base = Object.create({}, {
    init: {
        value: function() {
            //
            // default initialization here
            //
            print("Base.init");
        }
    }
});

var Derived = Object.create(Base, {
    //
    // override init
    //
    init: {
        value: function() {
            //
            // call base here
            //
            print("Derived.init");
            Object.getPrototypeOf(this).init.call(this);
        }
    }
});

Derived.init();

This produces the following output:

Derived.init
Base.init

This makes sense because I am calling init on the Derived instance and calling Object.getPrototypeOf on Derived should return a reference to Base which we are subsequently able to use to invoke its (i.e. Base’s) version of init. Wanting to make the syntax a tad more natural I decided to extend Object.prototype to include an “uber” getter property that will return a reference to the “base” object from which the current object inherits. Here’s what I came up with:

Object.defineProperty(Object.prototype, "uber", {
    get: function () {
        return Object.getPrototypeOf(this);
    },
    enumerable: false,
    configurable: false
});

This would now allow me to call the base like so:

var Derived = Object.create(Base, {
    //
    // override init
    //
    init: {
        value: function() {
            //
            // call base here
            //
            print("Derived.init");
            this.uber.init.call(this);
        }
    }
});

Derived.init();

Great. Now consider what happens in the following snippet:

var o1 = Object.create(Derived);
o1.init();

For all intents and purposes this perhaps looks like it should work (or it did so to me at least!). Turns out, this doesn’t quite work the way we might expect it to. Let’s step through what the JavaScript engine actually does when it encounters the call to init via o1.

  1. Does o1 have an “own” (see Object.hasOwnProperty) property called init? Nope, it does not.
  2. Does o1‘s prototype have an “own” property called init? o1‘s prototype is Derived and it does indeed have a property called init. Great, invoke Derived.init using o1 as the object context (Derived.init.call(o1)).
  3. The problem arises when the JavaScript engine encounters line 2 of Derived.init. Remember that "this" here is a reference to o1 and calling Object.getPrototypeOf on it is simply going to result in a reference to Derived being returned! So in effect, we are making a recursive call to Derived.init!

Taking it to its logical conclusion it is easy to see that this code will result in Derived.init being called over and over again till the JS engine runs out of stack space.

Adding a teeny bit of type metadata

If you think about the problem a bit you learn that the fundamental issue has to do with being able to somehow map member functions with the specific object where it is defined in such a way that this mapping is programmatically accessible at runtime. For example, we need to be able to associate the object Derived with its implementation of the method init. And this association must somehow be made accessible from Object.uber so that it can return the correct prototype object reference. One rather straightforward way that we could perhaps achieve this is by simply passing Derived to Object.uber. Like so:

Object.prototype.uber = function (obj) {
    return Object.getPrototypeOf(obj);
}

var Base = Object.create({}, {
    init: {
        value: function () {
            //
            // default initialization here
            //
            print("Base.init");
        }
    }
});

var Derived = Object.create(Base, {
    //
    // override init
    //
    init: {
        value: function () {
            //
            // call base here
            //
            print("Derived.init");
            this.uber(Derived).init.call(this);
        }
    }
});

var o1 = Object.create(Derived);
o1.init()

But I really wanted to be able to just say this.uber instead of having to pass the reference to the object where the method in question has been defined. This however will be possible only if we extend Object to include some additional support routines. First we add a function called inherit that is defined like so:

Object.inherit = function (proto, props) {
    var o = Object.create(proto, props);

    Object.getOwnPropertyNames(o).forEach(function (pn) {
        if (typeof (o[pn]) === "function")
            o[pn]["___type___"] = o;
    });

    return o;
}

Object.inherit simply delegates to Object.create and performs one small activity in addition. It enumerates all the member methods in the newly created object and tacks on a property called ___type___ to them. This property will simply point back to the newly created object. This bit of metadata will then be used from uber to retrieve a reference to the object where the method in question was created. With this new bit of metadata handy we modify uber to look like this:

Object.defineProperty(Object.prototype, "uber", {
    get: function () {
        var o = arguments.callee.caller["___type___"];
        if (!o) {
            throw "Uh oh! No metadata!";
        }
        return Object.getPrototypeOf(o);
    },
    enumerable: false,
    configurable: false
});

arguments.callee refers to the current function, i.e., the function where the current line is executing. This is particularly useful in situations such as the above where the function in question is an anonymous function and there really isn't any other way to refer to it. Function objects have a magic property called caller that become available as they are executing. Here's a small sample that illustrates this:

function bar() {
    print(bar.caller);
}

function foo() {
    bar();
}

foo();
print(bar.caller === null);

Here’s the output we get on running this snippet:

function foo() { bar(); }
true

As you can tell, outside of the call context bar.caller evaluates to null but while it is executing, it contains a reference to foo since bar was invoked from foo. We use this aspect of JS to access the function that invokes uber which in turn should contain a reference to the object where the function was defined via ___type___. Once we get that object it’s a simple matter of returning its prototype. With all this support infrastructure in place, code like the following should work just fine:

var Base = Object.inherit({}, {
    init: {
        value: function () {
            //
            // default initialization here
            //
            print("Base.init");
        }
    }
});

var Derived = Object.inherit(Base, {
    //
    // override init
    //
    init: {
        value: function () {
            //
            // call base here
            //
            print("Derived.init");
            this.uber.init.call(this);
        }
    }
});

var MoreDerived = Object.inherit(Derived, {
    init: {
        value: function () {
            print("MoreDerived.init");
            this.uber.init.call(this);
        }
    }
});

//
// create instances that inherit from MoreDerived
//
var o1 = Object.create(MoreDerived);
var o2 = Object.create(o1);
o2.init();

Here’s the output this produces:

MoreDerived.init
Derived.init
Base.init

OK, but what happens if somebody tacks on a new member method or overrides an existing one after Object.inherit? Will this.uber work from that method? Clearly, it won’t because the hidden ___type___ member is added to the member functions only from Object.inherit. This means that we’re going to have to add another little utility to Object that wraps this little functionality. Here goes:

Object.override = function (o, name, fn) {
    Object.defineProperty(o, name, {
        value: fn
    });
    fn["___type___"] = o;
}

Now, we can add new member methods to objects using this function. Here’s an example:

var o1 = Object.create(MoreDerived);
Object.override(o1, "init", function () {
    print("o1.init");
    this.uber.init.call(this);
});

var o2 = Object.create(o1);
Object.override(o2, "init", function () {
    print("o2.init");
    this.uber.init.call(this);
});

o2.init();

And here's the output we get:

o2.init
o1.init
MoreDerived.init
Derived.init
Base.init

That’s it. As long as we use Object.inherit and Object.override to create our derived instances and to override methods respectively, we can confidently use this.uber to refer to the correct parent prototype object at all times!

Link Comment (3)
 
blogorama home
about this blog
email the author
where on earth am i?
subscribe to mailing list
feeds Use these links for feed syndication
rss  |  atom
by category
technobabble (59)
philosophical crud (3)
irrelevant stuff (7)
archive
november, 2011 (2)
october, 2011 (1)
september, 2011 (7)
july, 2011 (3)
june, 2011 (2)
may, 2011 (3)
april, 2011 (1)
march, 2011 (1)
february, 2011 (1)
february, 2010 (1)
october, 2009 (1)
september, 2009 (1)
july, 2009 (5)
march, 2009 (2)
august, 2008 (2)
march, 2008 (1)
january, 2008 (1)
september, 2007 (2)
april, 2007 (1)
february, 2007 (2)
december, 2006 (1)
october, 2006 (1)
september, 2006 (4)
august, 2006 (3)
july, 2006 (4)
june, 2006 (3)
may, 2006 (6)
april, 2006 (2)
recent entries
Debugging existing...
Screen scraping wit...
Building an Instagr...
Building an Instagr...
Organizing your Jav...
290829 hits