What Good Is ‘this’? – The object reference parameter

I’m going to take a heterodox viewpoint today. Maybe it will provoke somebody to step up, flick their cigaret ash on my shoe, and say ‘Oh yeah? Here’s where you’re wrong, dimbulb…’ (Then again, maybe not.)

Have we been using the right syntax?

My contention is that we’ve all been idiots for typing ‘this’ in front of Doc object properties and methods all these years. (At least, it feels like years…) You know what I’m talking about:


var name = this.getField('name').value;

This is a typical example of the (unnecessary) use of ‘this’ as an object specifier. We use ‘this’ on the front of Doc object methods and properties to specify the current document’s Doc object. But as opposed to what? Another document’s Doc object? Adobe recommends against using any Doc object reference(s) to any remote document(s), for the simple reason that such references can be invalidated suddenly, without warning, if a file closes while the Doc reference is still open. To deal with the ‘dangling Doc reference’ problem, Adobe has come up with publish() and subscribe() methods for Acrobat 5.0 (available now, undocumented, in 4.05).

The JavaScript methodology

So if you’re not supposed to use a Doc object reference other than ‘this’, what good is ‘this’? It is no help to the JavaScript runtime engine. By default, the JavaScript interpreter always tries to scope methods like getField() (and properties like zoom and pageNum) to the current Doc object, which is to say the one in which the code is executing. So the use of ‘this’ as a scoping hint is absolutely meaningless, unless you’re violating Adobe’s advice on remote doc manipulations.

How to Break Your Pathetic Addiction to ‘this’

Get used to the fact that code incorporating Doc-object methods will work just fine without ‘this’ on the front. Use no object specifier at all. You can just write:

var name = getField('name').value;

Acrobat will not complain and your user will never know the difference. Your code will be cleaner, you’ll eliminate a lot of typing (which, for me, means fewer typos), and the JavaScript interpreter won’t barf. No men with black sunglasses will come to your door. No certified letters will arrive. The Thought Police will just add it to your existing rap sheet. (But Barry Scheck will get you off with a little community service. Don’t worry.)

Why ‘this’ Is Dangerous

I would contend that not only does ‘this’ serve no useful purpose whatsoever, it can actually be dangerous under certain circumstances. Let me show you an example. In the process, I can let you in on one of my favorite JavaScript hacks. Watch closely.

In JavaScript, existing object classes (such as String, Date, etc.) have a prototype property that, if you attach new references to it, modifies the original definition of the root object. This can be extremely handy when and if you find it necessary to modify the core object to take a new property or method of your own design.

For a quick example, let’s just suppose that we would like to modify the Array class such that there is a new method, rotate(), which moves all array members to the right while popping the last member off and reattaching to the front of the array list. Here’s how you could add that method to the root class:

Array.prototype.rotate = function() { 

this.unshift(this.pop());return this; }

Let’s look at this code. What we’ve done is attach a new method (function) to the Array class using the prototype hook. Our new function has no arguments. It returns the array, with members rotated. The unshift() method adds a new item to the beginning of the array, moving all other items over. The item we’re adding, however, is the tail item of the original array. So we’ve achieved the goal of moving all items over one place while relocating the tail-end item to the start of the array.

After the above code executes, ANY new Array you construct with the Array constructor will have a rotate() method. What’s more, your existing arrays will also have that method! It’s almost magical.

Example:

var n = new Array(1,2,3,4);
var m = n.rotate(); // 'm' is [4,1,2,3]

I’m sure you noticed one peculiar thing about the foregoing code, which is that I used

‘this’ on the front of the unshift() and pop() methods. Why did I do this?

Because I want to refer to the parent array. I have no reference to it (no arguments were

passed in), so the prototype property lets me get the reference I need by using ‘this’.

Inside the rotate function definition, ‘this’ is scoped to the parent object, not the Doc

object.

Here’s how you can get in trouble: If you try a call to this.getField() in the

above code, it will fail. That’s because the JavaScript interpreter considers ‘this’

to be scoped to the function’s parent object, not to the Doc object.

What is the solution?

The ONLY way to get any Doc object methods or properties to work properly in the code for

rotate() is to leave off the ‘this’ specifier.

If you call getField(), completely bare, inside the rotate() function, it will

work. (Ditto for zoom, pageNum, and all the rest.) If you put ‘this’ on the front, your code

will fail.

I call ‘this’ trouble.

What’s your take?

You May Also Like

About the Author: Kas Thomas

Leave a Reply