A Lesson on JavaScript Objects and Prototype’s bindAsEventListener Method

This post covers 3 topics about JavaScript:

  • How objects work in JavaScript and what makes them useful.
  • A concise explanation as to why the this variable is confusing at times.
  • A clear explanation of bindAsEventListener since the official one is confusing at best.

An Overview of JavaScript Objects

To dumb things down, in JavaScript, functions can be assigned to variables. Thus, you can do cool stuff like this:

var eat = function() {
    alert(‘munch, munch’);
};
// displays ‘munch, munch’
eat();

Objects are denoted by using curly brackets. Inside an object, you can put variables. The syntax is a little different, so pay attention. Thus:

var Michi = {
    favoriteFruit: ‘banana’,
    favoriteBread: ‘whole grain’
};
// displays ‘banana’
alert(Michi.favoriteFruit);

Note: I don’t like either of those that much.

The colon is sort of an equals sign. It essentially equates to “variable name: value”. Each assignment is separated by a comma and the “value” portion can be anything that you can assign to a regular variable. Since you can assign variables inside objects, that means you can put functions inside objects. Then you can call a function by putting a pair of parentheses () on the end of the variable. Again, pay attention to the syntax:

var Michi = {
    eatFruit: function() {
        return ‘Eating: banana’;
    }
}
// displays ‘Eating: banana’
alert(Michi.eatFruit());

In a truly object oriented example, calling eatFruit() should cause Michi to eat his favoriteFruit variable:

// does the same thing as the previous example
var Michi = {
    favoriteFruit: ‘banana’,
    eatFruit: function() {
        return ‘Eating: ‘ + this.favoriteFruit;
    }
}

This is where stuff gets sticky. Or maybe gooey. Nah, I won’t make a pun here. this refers to Michi. This is important because later we might copy Michi into another variable Tom. When that happens, this now refers to Tom‘s favorite fruit, which might be an orange. this is a dynamic placeholder for whatever object that we are inside of.

How *this* Complicates Things

Let’s continue illustrating the problem by building another example:

function watch(personEating) {
    alert(personEating);
}
// displays “Eating: banana”
watch(Michi.eatFruit());

This will do exactly what you think it will do. It will cause Michi to eatFruit(). However, the next example is where things get very tricky:

function watch(personEating) {
    alert(personEating());
}
// the goal is to display “Eating: banana”
watch(Michi.eatFruit);

This will fail. Why? Notice the very subtle differences between the two examples. Look at section I highlighted. In the first example, the function is called and its result, the text “Eating: banana” is then sent to alert(). In the second example, the function Michi.eatFruit is passed in as a variable. It is then called as a function from inside watch(). Translated, that code renders like this:

function watch(personEating) {
    // this temp stuff isn’t necessary, but it should make
    // things easier to understand

    var tempFunction = function() {
        return ‘Eating: ‘ + this.favoriteFruit;
    }
    var tempText = tempFunction();
    alert(tempText);
}

As you can see, the problem is due to the this.favoriteFruit variable. this now refers to the function watch()‘s parent (e.g., nothing at all), which doesn’t have a favoriteFruit variable. this no longer refers to Michi. This is a very common and very frustrating part about JavaScript. To get around this, the popular prototype library has a fix.

Prototype’s bindAsEventListener

The official documentation (as of this writing) for this method is dead wrong. Their example is wrong. Their explanation is fuzzy. Maybe somebody over there will read this and fix it up. Prototype’s example doesn’t even work! The corrected example is:

var obj = { name: ‘A nice demo’ ,
    handler: function (e) {
        var tag = Event.element(e).tagName.toLowerCase();
        var data = $A(arguments);
        data.shift();
        alert(this.name + ‘\nClick on a ‘ + tag + ‘\nOther args: ‘ + data.join(‘, ‘));
    }
};
Event.observe(window, ‘click’, obj.handler.bindAsEventListener(obj, 1, 2, 3));

So I will try to explain how to use it correctly. The syntax is simple:

parentObject.someFunction.bindAsEventListener(parentObject);

Thus, in my previous example that broke, you would rewrite it as follows:

function watch(personEating) {
    alert(personEating());
}
// was watch(Michi.eatFruit);
watch(Michi.eatFruit.bindAsEventListener(Michi));

When the code is executing, it knows that this refers to Michi, thanks to that argument being passed in. The argument represents what this refers to. So you would still call the method exactly as you normally would, but you tack bindAsEventListener on the end.

I hope this was educational. The fixed demo code will run for certain since I tested it; the rest: I am not as sure (95%).

REMEMBER: Word Press likes to convert my quotation marks into the slanted ones. So if you cut and paste my code, make sure you change those!

Sony Planned to Upgrade the PS3 but Microsoft Beat Them to It

I find this infuriatingly stupid: Sony has (inadvertently) revealed plans to release a new PS3 that has a 80Gb hard drive. It’s not that I don’t like the upgrade; I don’t agree with the decision to upgrade now. A product that has been in the market for barely 6 months (wait, no, it hasn’t) is not ready for an upgrade. It was only released this week in Europe!

Why in the world are they trying to upgrade the hardware? To attract more buyers? Allow me to point out a simple flaw in their reasoning:

  1. Build the biggest and best console
  2. Wait for people to come buy it by the cart full
  3. Realize sales are tepid and panic
  4. Make the biggest and best console even “better” by upgrading it
  5. Wait for people to come buy it by the cart full

It’s a commonly known fact that the “if you build it they will come” strategy is poor at best. And clearly, they built it and they didn’t get anywhere near what they thought they’d attract. Now they hope on attracting more people by following the same retarded logic from the first time around. By starting this measure so early, they risked a leak. And boy did it leak. So now anybody thinking about a PS3 has a real incentive to wait. I mean how mad would you be if you bought a 20Gb PS3 only to have it “discontinued” the next day? Good way to slow your sales there, Sony.

And what about the increased cost of the drive? Why add $5 per machine when you could save that difference and get your product to stop bleeding away your hard earned profits. What’s 20Gbs anyway? If you’re going to do an upgrade, at least do it like Microsoft and go big (120Gb). Not to mention the upgraded 360 comes in its own color, allowing for extra bragging rights to adopters.

Sony is approaching this all wrong. They made critical assumptions when designing their product which turned out to be wrong. But instead of correcting those mistakes, they continue down the same path. In constrast, Microsoft is doing an amazing job. They resisted the urge of bundling the HD-DVD player. Microsoft has a lot to gain by the HD-DVD format becoming accepted, but they recognize that bundling the player for $200 would be a critical error that will price them straight out of the market.

I don’t think Sony realizes it yet, but they are boxing at Microsoft’s pace. And Microsoft knows exactly where they’re headed, while Sony seems to be caught off guard more and more frequently. Now, it looks as if the 360 is a far better deal, coming with nearly double the capacity of the lower model for less money. If there’s one measure any consumer can understand, it’s hard drive capacity.

This may also be Microsoft’s power play to get Sony to match them at 120Gb, in hopes of further increasing the cost of PS3 production and hurt Sony’s bottom line. Sony can’t possibly raise the price of the PS3, so they’d have to eat the added costs. That, or they let Microsoft take the crown for disk capacity. This is an extremely difficult move for Sony to mimic. In short, it is a deviously smart business move by Microsoft.

How I Choose What I Write About

Today’s real update will have to come in the afternoon seeing as I’m exhausted right now. 🙂 There was once a time when working 16 hour days didn’t phase me. It sucks to get old! Well, and it’s 3am.

Since I’m nearly brain-dead now, I thought I’d keep this one simple and give you guys a little bit of insight on how I pick what I write about each day:

  1. If I encounter a really hard programming problem at work, I will blog about the solution. These posts drive my search traffic.
  2. Programming posts don’t count toward my goal of one post each weekday. Weekends posts are a bonus to my readers. When I do a programming post, I couple it with a second post. Only when you are really unlucky (or lucky, depending on who you are) will that second post also be a programming post.
  3. I often skip coverage of major developments that have no real insight to add. For example, I recently skipped coverage of Dvorak’s anti-iPhone post (he’s dumb, and everybody knows it), YouTube’s new live chat feature (cool, but important), and developments in the RIAA lawsuits (they’re losing). My logic is that I only have about one hour a day (tops) to commit to a post so I might as well pick a good topic.
  4. My favorite companies to write about are: Google, Apple, Microsoft, and Yahoo. These companies have their hands in many industries, and it is interesting to see how they juggle their competing internal interests. Better yet, it is fascinating how they bring them together.
  5. I try to put double thought into one post a week. Last week was my YouTube post. This week was my stats post (or maybe my Yahoo or Google Checkout post). My goal is to write something good enough that I will gain one new regular reader a week. 🙂
  6. If I see news about e-paper, I will very likely post about it. As I’ve said before, I believe this technology will become as pervasive as the LCDs in the next decade. If there’s any technology outside of the web that I am a fan of, it is e-paper.

So if you have a topic you’d like me to cover more often, feel free to ask. Today, either later in the afternoon or evening, I will be writing about Sony’s further idiocy and how to submit better articles to sites like Digg. Yes, I’ve noticed some of you are submitting my work. I appreciate it, but it could be done better. 🙂