Why I like JavaScript (Part I)

* - *
|

I really like a lot of things about JavaScript. With the exception of a few bizarre syntactic constructs, I think it's the most sensible thing going. Of course, I have a loose-typing, runtime bias so you can send me your flames about how that proves I'm a drooling, barely computer-literate script kiddie, but I promise that I won't read them.

Anyway, here's one thing that I find particularly nifty about JavaScript. It's a concept that I've seen referred to as "protection."

Given an object o which has slot n set to 6

    var o = { n : 6 };

I can create another object, oprime, which uses o as its __proto__. (Remember I mentioned the bizarre syntactic constructs? Well this is an example of bad syntax for a useful feature.)

    var oprime = { __proto__ : o };

If an object is your __proto__, that means that when the runtime goes to look for the value of one of your slots, if you haven't defined it, then the runtime looks for that slot in your __proto__. If it's not there, then the runtime looks in that object's __proto__, and so on. The object Object (ok, there's another bizarre syntactic construct -- every object in a JavaScript ultimately descends from the object named... "Object". Bad name, but decent idea) is at the root of every __proto__ chain.

Anyway, this is the essence of inheritance, but boiled down into something very pure and simple. So given the statements above, the expression:

    oprime.n == 6

is true. Also, I can affect the value of oprime's n slot by changing the value of o's n slot. So this:

    o.n++;
    oprime.n == 7;

is also true, even though oprime has no slots, and technically the runtime hasn't even had to allocate any memory for it yet. (In fact, the runtime probably has already allocated a bucket for its slots, and the global slot oprime is a pointer to that bucket.)

Now, consider what happens when I write this:

    oprime.n++;
    oprime.n == 8;

(The last statement is true by the way.) What happens here? Well, I think this is pretty nifty. The runtime gets the value for the n slot, which is 7, and then sets it on oprime, so now oprime has its own n slot, which masks the value of o's n slot. We could prove this a couple of ways, but the easiest is to simply delete the slot in oprime.

    delete oprime.n;
    oprime.n == 7;

Pleasant, no? Also pleasant is the fact I won't affect o by calling stuff on oprime. So for instance, if I try to delete n again:

    delete oprime.n;
    oprime.n == 7;

The last statement is still true.

I wrote a little unit test using Laszlo to prove all of this. Feel free to play with the source.

EDIT PROGRAM

<canvas>
    <include href="lzunit"/>
    <TestSuite>
        <TestCase>
            <method name="test">
                var o = { n : 6 };
                var oprime = { __proto__ : o };
                AssertEquals( 6 , oprime.n );
                o.n++;
                AssertEquals( 7 , oprime.n );
                oprime.n++;
                AssertEquals( 8 , oprime.n );
                delete oprime.n;
                AssertEquals( 7 , oprime.n );
                delete oprime.n;
                AssertEquals( 7 , oprime.n );
            </method>
        </TestCase>
    </TestSuite>
</canvas>
|
* * *